微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么将绑定注入 UIViewControllerRepresentable 会导致保留循环?

如何解决为什么将绑定注入 UIViewControllerRepresentable 会导致保留循环?

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

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

而且看起来绑定完全被破坏,UIViewControllerRepresentable 不再工作

在查看它时,Coordinator(self) 很糟糕是有道理的,但是 Apple 自己的文档说要这样做。我错过了什么吗?

这是一个简单的例子:

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()
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。