0

因此,当将作为已发布属性的绑定从 ObservableObject 注入 UIViewControllerRepresentable 时,似乎存在一个保留周期。

似乎如果您在另一个视图中创建一个视图,并且第二个视图具有 ObservableObject 并将其发布的属性注入 UIViewControllerRepresentable 然后在协调器中使用,则在刷新原始视图时永远不会释放 ObservableObject。

此外,Binding 看起来完全被破坏了,并且 UIViewControllerRepresentable 不再起作用

看着它,Coordinator(self) 不好是有道理的,但苹果自己的文档说要这样做。我错过了什么吗?

这是一个简单的例子:

struct ContentView: View {
    @State var resetView: Bool = true
    var body: some View {
        VStack {
            OtherView()
            Text("\(resetView ? 1 : 0)")
            // This button just changes the state to refresh the view
            // Also after this is pressed the UIViewControllerRepresentable no longer works
            Button(action: {resetView.toggle()}, label: {
                Text("Refresh")
            })
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct OtherView: View {
    @ObservedObject var viewModel = OtherViewModel()
    var body: some View {
        VStack {
            Text("Value: \(viewModel.value)")
            Wrapper(value: $viewModel.value).frame(width: 100, height: 50, alignment: .center)
        }
    }
}

class OtherViewModel: ObservableObject {
    @Published var value: Int
    
    deinit {
        print("OtherViewModel deinit") // this never gets called
    }
    
    init() {
        self.value = 0
    }
}

struct Wrapper: UIViewControllerRepresentable {
    @Binding var value: Int
    class Coordinator: NSObject, ViewControllerDelegate {
        var parent: Wrapper
        init(_ parent: Wrapper) {
            self.parent = parent
        }
        func buttonTapped() {
            // After the original view is refreshed this will no longer work
            parent.value += 1
        }
    }
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    func makeUIViewController(context: Context) -> ViewController {
        let vc = ViewController()
        vc.delegate = context.coordinator
        return vc
    }
    func updateUIViewController(_ uiViewController: ViewController, context: Context) {}
}

protocol ViewControllerDelegate: class {
    func buttonTapped()
}

class ViewController: UIViewController {
    weak var delegate: ViewControllerDelegate?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        let button = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 20))
        button.setTitle("increment", for: .normal)
        button.setTitleColor(UIColor.blue, for: .normal)
        button.addTarget(self, action: #selector(self.buttonTapped), for: .touchUpInside)
        self.view.addSubview(button)
    }
    @objc func buttonTapped(sender : UIButton) {
        delegate?.buttonTapped()
    }
}
4

0 回答 0