Putting custom view in .contextMenu() on SwiftUI creates permanent memory leak

here is a minimal reproducible example, on macOS

struct ContextMenuTest1: View {
    @State var visible: Bool = true

    var body: some View {
        Button(action: { self.visible.toggle() }, label: { Text("ContextMenuTest2 Toggle") })
        if self.visible {
            ChildView()
        }
    }

    struct ChildView: View {
        class Model: ObservableObject {
            init() {
                print("Model Created")
            }

            deinit {
                print("This will never be called")
            }

            func someAction() {

            }
        }

        var body: some View {
            Text("Text That has Context Menu")
                .contextMenu {
                    ContextMenu()
                }
        }

        struct ContextMenu: View {
            @StateObject var model: Model = .init()

            var body: some View {
                Button(action: {
                    self.model.someAction()
                }, label: {
                    Text("Context Menu Button 1")
                })
            }
        }
    }
}

step to reproduce :

  1. right click on Text("Text That has Context Menu") to open contextMenu()
  2. turn off the contextMenu
  3. click "ContextMenuTest2 Toggle"

This should have destroyed both ChildView and ChildView.ContextMenu, thus should have deallocated ChildView.Model but ChildView.Model.deinit never be called.

I understand .contextMenu() document show examples of putting Button directly, but it doesn't mention or block attempts of putting custom view directly like this - in which case, Button.action closure it permanent memory leaked. unless you kill the application

hope that clairify the bug, thanks!

Putting custom view in .contextMenu() on SwiftUI creates permanent memory leak
 
 
Q