SwiftUI中@State变量的生命周期是什么?
如果我创建一个新的SwiftUI中@State变量的生命周期是什么?,swift,swiftui,Swift,Swiftui,如果我创建一个新的@State变量,它什么时候会被销毁?它是否在父级UIHostingController的生命周期内有效 据我所知,它没有被记录在案。这是相关的,因为如果我在视图层次结构中的某个地方创建一个observateObjectasState,我不知道如何在事后清理 import SwiftUI struct Example: View { @State private var foo = Foo() var body: some View { Tex
@State
变量,它什么时候会被销毁?它是否在父级UIHostingController
的生命周期内有效
据我所知,它没有被记录在案。这是相关的,因为如果我在视图层次结构中的某个地方创建一个observateObject
asState
,我不知道如何在事后清理
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)
}
}
问题在于视图
类型是一个结构
,它的主体
不是一组实时执行的函数,而是在呈现视图
主体的同时实际初始化的函数
问题场景:
如果您注意到,Example.init
甚至在导航出现之前就被调用了,而在弹出的Example.deinit
上根本没有被调用。这是因为当ContentView
被初始化时,它也必须初始化它的主体中的所有内容。因此将调用Example.init
当我们导航到Example
时,它已经初始化,因此不会再次调用Example.init
。当我们从Example
中弹出时,我们只需返回ContentView
,但由于可能需要再次使用Example
,并且由于它不是实时创建的,因此不会被销毁
示例。仅当必须完全删除ContentView
时,才会调用deinit
我对此不确定,但在这里发现另一篇文章讨论了类似的问题:
为了证明这一点,让我们确保ContentView
被完全删除。
下面的示例使用操作表来显示它并将其从视图层次中删除
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!")
}
}
工作场景:
PS:这适用于类,即使未声明为@State
,并且与iOS 14中的ObservableObject
没有任何关系,正确的方法是使用@StateObject
我不太熟悉State
或SwiftUI
,但它不仅仅基于Foo
ie的类型,如果它是引用类型,那么每当它的retain计数向下移动到零时。如果它是一个变量类型,那么你真的不关心它们的生命周期。问题是,如果有可能,该变量将在SwiftUI中被deinit
删除。将observeObject
作为状态
至少是一种误解,它必须与observeObject
配对。此外属性包装状态(和ObservedObject)是struct,value type。“因此,当视图消失时,变量也消失了。”但在我的测试中不是这样,在我的示例中,deinit
从未被调用。@WilGieseler Ok,我将在操场上看一看test@WilGieseler我可以调用deinit
,但我必须确保视图被删除。我已经更新了答案。你的答案使用了private var foo=foo()
而不是@State private var foo=foo()
,我认为这可能是问题的症结所在?呃,不,也许不是,我正在试图找出一个涉及@State
和@observeable
对象的问题,但很难简化复制。还在努力。。。
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()
}
}
}
}