为什么将绑定注入 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 (将#修改为@)

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...