如果我在SwiftUI中有一个ObservableObject,我可以将其称为@ObservedObject:

class ViewModel: ObservableObject {
    @Published var someText = "Hello World!"
}

struct ContentView: View {
    @ObservedObject var viewModel = ViewModel()
    
    var body: some View {
        Text(viewModel.someText)
    }
}

或者作为@StateObject:

class ViewModel: ObservableObject {
    @Published var someText = "Hello World!"
}

struct ContentView: View {
    @StateObject var viewModel = ViewModel()

    var body: some View {
        Text(viewModel.someText)
    }
}

但两者之间的实际区别是什么?有没有一种情况比另一种更好,或者是两种完全不同的东西?

推荐答案

@ObservedObject

当视图创建自己的@ObservedObject个实例时,每次丢弃并重新绘制视图时,都会重新创建它:

struct ContentView: View {
  @ObservedObject var viewModel = ViewModel()
}

相反,当视图被重新绘制时,@State变量将改变其值.

@StateObject

@StateObject@ObservedObject@State的组合——ViewModel的实例将被保留并重新使用,即使在视图被丢弃和重新绘制之后:

struct ContentView: View {
  @StateObject var viewModel = ViewModel()
}

Performance

虽然如果视图经常被迫重新创建重量级对象,@ObservedObject可能会影响性能,但当@ObservedObject不复杂时,这应该无关紧要.

When to use @ObservedObject

现在似乎没有理由使用@ObservedObject,那么什么时候应该使用呢?

您应该将@StateObject用于任何您需要的可观察属性

请注意,可能的用例太多,有时在您的视图中重新创建一个可观察的属性可能很困难.在这种情况下,最好使用@ObservedObject.

有用的链接:

Swift相关问答推荐

如何更新Square Order?

当我点击模拟器中的文本字段时,UIKit CLLocationButton崩溃

在解码字符串时需要帮助.

如何分解阿拉伯字母?

我可以在预览中通过拖动手势跳转,但在模拟器中失败

仅当单击UIButton时才调用计时器函数

如何将新事例添加到枚举中?

为什么变量不存储在 Swift 的过程数据区中

VisionOS TabBar预览中是否存在漏洞?

应该在ViewModel还是ViewController中使用"Task {}"?

我如何读取并通知可可 macos 中某个类的计算(computed)属性?

deinitialize() 与 deallocate()

ZStack 中的 ProgressView 与 View 的行为不同

临时添加到视图层次 struct 后,Weak view引用不会被释放

NSFontAttributeName 已更改为 String

不支持用作符合协议 AnyObject 的具体类型

在 unwind segue 之后执行 push segue

如何在 Swift 中使用 Crashlytics 登录?

Swift 2.0 最低系统版本要求(部署目标)

使用 JSONEncoder 对类型为 Codable 的变量进行编码