【发布时间】:2021-10-25 14:54:57
【问题描述】:
我正在使用@StateObject 为我的视图创建视图模型。问题是 ViewModel 在关闭视图后仍在内存中,并且从未调用 deinit。如果我打开和关闭视图 10 次,调试内存图会显示 10 个 ViewModel。我创建了一个非常简单的示例来复制问题:
import SwiftUI
struct MySwiftUIView: View {
@Environment(\.presentationMode) private var presentation
@StateObject var viewModel = MyViewModel()
var body: some View {
Text("Hallo World.")
.navigationBarBackButtonHidden(true)
.navigationBarItems(leading: Button(
action: {
presentation.wrappedValue.dismiss()
},
label: { Text("back") }))
}
}
class MyViewModel: ObservableObject {
init() {
print(">> init")
}
deinit {
print("[x] deinit")
}
}
每次打开视图时都会打印“>> init”,但从不打印“[x] deinit”。
这就是我打开视图的方式:
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
VStack{
NavigationLink(destination: MySwiftUIView()){Text("NavigationLink")}
}
}.navigationViewStyle(StackNavigationViewStyle())
}
}
有人知道为什么 ViewModel 永远不会被破坏吗?
我在 Xcode 中创建了一个演示项目,可以在这里找到:https://file.io/QQnHDvRNaGPP
【问题讨论】:
-
我正在使用 XCode 13 beta 5,它对我来说可以正常工作。当按下后退按钮时,deinit 打印正确。
-
@runemonster 这个问题不是针对iOS 15的,所以请在当前稳定的iOS版本上测试。人们现在遇到问题,即使它在 iOS 15 中得到修复,他们也在寻找当前版本的解决方案,当它被 iOS 15 取代时,许多支持它的人仍然需要修复。
-
所以我测试了 ViewModel 没有正确调用 deinit 的原因是
navigationBarItems在关闭时没有正确删除对页面的所有引用。您的应用程序的目标版本是什么?如果它是 14 或更高,您可以更新到ToolbarItem这将使您的 deinit 被正确调用。 -
@runemonster:我的目标版本是iOS14。谢谢你的tipp,我会试试的。
-
如果你因为某种原因必须使用
navigationBarItems。这个堆栈答案应该会有所帮助。我试过了,它奏效了。 stackoverflow.com/a/61305155/6122879