首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >@观测对象模型生命周期?

@观测对象模型生命周期?
EN

Stack Overflow用户
提问于 2021-07-04 15:06:36
回答 1查看 367关注 0票数 0

我正在测试@ObservedObject,以测试SwiftUI如何处理模型的生命周期。

正如我现在所理解的,从WWDC的视频和文档中,创建模型对象的视图(一个采用ObservableObject的类)应该使用@StateObject

从WWDC视频中,他们清楚地指出,@ObservedObject 并不拥有观察到的实例生命周期。

所以我创建了这个简单的设置:

代码语言:javascript
复制
struct TestParentView: View {
    
    @ObservedObject var model:TestModel
    
    var body: some View {
        
        VStack {
            Text("TEST TEXT. \(model.name)")
            TestChildView(model: model)
        }
    }
    
}

struct TestParentView_Previews: PreviewProvider {
    static var previews: some View {
        TestParentView(model: TestModel())
    }
}



struct TestChildView: View {
    
    
    @ObservedObject var model:TestModel
    
    var body: some View {
        
        Button(action: {
            print("change name")
            model.changeName()
        }, label: {
            Text("Change Name")
        })

    }
    
}

struct TestChildView_Previews: PreviewProvider {
    static var previews: some View {
        TestChildView(model: TestModel())
    }
}

我在这里使用的模型是:

代码语言:javascript
复制
class TestModel:ObservableObject {
    
    @Published var name:String = ""
    let id = UUID()
    
    
    func changeName() {
        name = "\(UUID())"
    }
    
    deinit {
        print("TestModel DEINIT. \(id)")
    }
    
}

当我运行这个应用程序时,我希望在TestParentView中创建的TestParentView实例至少在某个时候被去初始化,因为@ObservedObject并不拥有model的生命周期。

当我点击按钮来触发名称更改时,所有的更改都会生效,但是TestModel DEINIT不会被调用。

从这一切来看,TestParentView似乎有一个对TestModel的强引用,而且它从不让它离开。

那么,在这种情况下,当他们说@ObservedObject不管理model的生命周期时,这意味着什么呢?

如果TestModel没有管理模型的生命周期,为什么@ObservedObject从未调用过?

很明显我漏掉了什么。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-07-06 15:35:43

假设此视图:

代码语言:javascript
复制
struct Foo: View {
    @ObservedObject var model = TestModel()

    var body: some View {
        Text(model.name)
    }
}

每次创建此视图时,它都会实例化TestModel的一个新实例。

SwiftUI视图实际上更像视图描述,在应用程序生命周期中创建和销毁了很多视图。因此,结构轻量级是很重要的。Foo视图并不是很轻量级,因为每次呈现传递它都会实例化一个新模型。

如果您使用@StateObject,框架将只在第一次实例化TestModel。在此之后,它将重用同一个实例。这使得它更有表现力。

经验法则:

如果视图创建自己的模型(如Foo视图),则使用@StateObject.

  • If从外部传入模型,使用@ObservedObject.

回答您的问题:“为什么TestModel DEINIT从未调用”.

您可以这样说:“当我运行这个应用程序时,我希望在TestParentView中创建的TestParentView实例至少在某个时候被去初始化”。

微妙的细节是,TestModel是而不是在TestParentView中创建的,它只是传入。

它在TestParentView_Previews中创建。而且,由于TestParentView_Previews的主体只执行一次,所以TestModel也只能初始化一次,因此永远不会被释放。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68246045

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档