SwiftUI中@State变量的生命周期是什么



如果我创建一个新的@State变量,它什么时候被销毁?它是否能在父UIHostingController的一生中生存?

据我所知,它没有记录在案。这是相关的,因为如果我在视图层次结构中的某个位置将ObservableObject创建为State,我不知道如何在自己之后进行清理。

import SwiftUI
struct Example: View {
@State private var foo = Foo()
var body: some View {
Text("My Great View")
}
}
class Foo: ObservableObject {
deinit {
// When will this happen?
print("Goodbye!")
}
}

假设:

struct Example: View {
@State private var foo = Foo()
var body: some View {
Text("My Great View")
}
}
class Foo: ObservableObject {
init() {
print(#function)
}
deinit {
print(#function)
}
}

问题是View类型是struct,而它的body不是实时执行的函数集合,而是在呈现Viewbody的同时实际初始化的函数。

问题场景:

struct ContentView: View {
@State var isPresented = false
var body: some View {
NavigationView {
NavigationLink(destination: Example()) {
Text("Test")
}
}
}
}

如果您注意到,甚至在导航发生之前就调用了Example.init,而在弹出窗口中根本不调用Example.deinit。原因是当ContentView被初始化时,它也必须初始化它的body中的所有内容。因此Example.init将被调用

当我们导航到Example时,它已经初始化,因此不会再次调用Example.init。当我们跳出Example时,我们只是回到ContentView,但由于可能再次需要Example,而且它不是实时创建的,因此不会被销毁。

只有在必须完全移除CCD_ 21时才会调用CCD_。

我不确定这一点,但在这里发现了另一篇关于类似问题的文章:

  • SwiftUI和如何不初始化可绑定对象

为了证明这一点,让我们确保ContentView被完全移除
以下示例使用操作表来显示它,并将其从视图层次结构中删除。

工作场景:

struct ContentView: View {
@State var isPresented = false
var body: some View {
Button(action: { self.isPresented.toggle() }) {
Text("Test")
}
.sheet(isPresented: $isPresented) {
Example()
.onTapGesture {
self.isPresented.toggle()
}
}
}
}

PS:这适用于类,即使没有声明为@State,也与ObservableObject没有任何关系。

在iOS 14中,正确的方法是使用@StateObject。没有安全的方法将引用类型存储在@State中。

最新更新