我有这样的东西:
struct SomeView: View {
@ObservedObject var viewModel: SomeViewModel
var body: some View {
NavigationView { // <- culprit
Button(action: { self.viewModel.logOut() }) { Text("X").frame(width: 40, height: 40) }
}
}
class SomeViewModel: ObservableObject {
func logOut() {
// changes global state, based on which the views are swapped, so `SomeView` is removed and replaced by a different one
}
}
按下按钮时,SomeView
将关闭,并显示另一个视图。但是,如果我检查内存图,则SomeViewModel
仍然被分配,因为在Button的操作闭包中调用了self.viewModel.logOut()
,并且Button持有对SomeViewModel
的引用。
有什么解决办法吗?
编辑:
实际上,当不将按钮不包装在NavigationView
中时,没有泄漏。一旦包裹好按钮,就会出现泄漏。包装VStack
可以正常工作。但是用Form
包装会再次产生泄漏。这里似乎是同样的问题:SwiftUI - Possible Memory Leak
答案 0 :(得分:4)
我找到了解决方法:在您的操作中使弱viewModel
。苹果似乎改变了关闭的行为。这意味着NavigationView
存储着对viewModel的强引用。经过几天的调试,它终于对我有用。
Button(action: {
[weak viewModel] in viewModel?.dismissButtonPressed.send(())
}) {
Image("crossmark")
.padding()
.foregroundColor(Color.white)
}
}
在您的问题中,将通过以下方式解决此问题:
NavigationView {
[weak viewModel] in Button(action: { viewModel?.logOut() }) {
Text("X").frame(width: 40, height: 40)
}
}
在最新的Xcode 11.5和iOS 13.5上进行了测试。现在,关闭视图后,viewModel
被正确释放。