因此,当将作为已发布属性的绑定从 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()
}
}