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
as
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)
    }
}
问题在于
视图
类型是一个
结构
,它的
主体
不是一组实时执行的函数,而是在呈现
视图
主体的同时实际初始化的函数

问题场景: 如果您注意到,
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()
            }
        }
    }
}