我对SwiftUI的NavigationView堆栈中的内存管理工作方式有疑问。我有一个视图,在其中我声明了NavigationView和NavigationLink,导航功能良好,但当我从堆栈(例如向上的返回按钮)弹出视图时,控制台上没有打印销毁(deinit)信息,并且TestViewModel仍然可以在内存图中找到。当不再需要时,如何取消初始化我的TestViewModel?
/// First view in application
struct ContentView: View {
var body: some View {
NavigationView {
VStack {
Text("Hello, leak!")
NavigationLink(
destination: TestView(viewModel: TestViewModel()),
label: { Text("Create leak ♂️") }
)
}
}
}
}
/// Just simple class for init and deinit print
class TestViewModel: ObservableObject {
@Published var text = "Test"
init() {
print("TestViewModel init")
}
deinit {
print("TestViewModel deinit")
}
}
/// Second view, which is poped from stack
private struct TestView: View {
@ObservedObject var viewModel: TestViewModel
var body: some View {
Text(viewModel.text)
}
}
更新 添加了内存图截图,我之前忘记了。
更新
在真实设备上测试,导航正常工作。看起来,当弹出视图时,视图模型没有被销毁,但在下一次推入视图时重新初始化了。但问题仍然存在,有没有办法在导航栈中弹出视图时销毁视图模型?
TestViewModel init
TestViewModel deinit
TestViewModel init
另外,当我将另一个视图添加到堆栈中时,行为会有所改变。现在,第二个视图的视图模型将导致泄漏,但是第一个视图将按预期被取消初始化。
First view push
TestViewModel init
Second view push
TestViewModel2 init
Second view pop
First view pop
TestViewModel deinit