@State vs @ObservableObject - 哪个和什么时候?

@State vs @ObservableObject - which and when?

我目前正在熟悉 SwiftUI 和 Combine 框架。我并没有真正理解这两种方法之间的区别。当我们必须跟踪一些数据(比如任务列表)时,我们可以声明一个@State 变量,它的变化会自动发送通知并更新当前视图。但是,看起来也可以这样做:

class TaskList: ObservableObject{
    //a list that's going to be modified and updated on different occasions
    @Published var list: [String]
}

class TodoListView {
    @ObservedObject var todoList = TaskList()
}

所以,我漏掉了一点 - @State 和 @ObservedObject 的方法有何不同,在什么情况下哪个更可取?

谢谢!

主要区别在于 @State 用于结构,而 @ObservedObject 用于 类。 @State@ObservedObject 都实现了类似的目的,即在发生变化时通知您。

A struct 在某些 属性 发生突变时发生变化,这意味着它会重新创建,因此 @State 会更新。当 属性 发生变化时,class 会更新 @ObservedObject - 使用 @Published 来监听变化。当更新 @State@ObservedObject 时,将重新制作视图主体。

你在这里真正问的问题是 when to use a struct vs a class 在某些情况下是否可行。

在你的例子中,因为 TaskList 只是一个基本的数据结构,不需要很多你想阻止更新视图的属性(通过 using/not 使用 @Published ),你应该使用 struct@State 来代替。

如果您在 SwiftUI View 中将任何变量标记为 @State 并将它们绑定到 Viewbody 内的 属性,则body 将在 @State 变量更改时重新计算,因此您的整个 View 将被重新绘制。此外,@State 变量应作为 View 的唯一真实来源。由于这些原因,@State 变量只能从 Viewbody 中访问和更新,因此应该声明为 private.

当您绑定某些用户输入时(例如 TextField 的值或从 Picker 中选择的值),您应该使用 @State@State 应该用于 值类型 structs 和 enums)。

另一方面,@ObservedObject 应该用于引用类型(classes),因为只要 @Published 属性 ObservableObject 变化。

当您有一些数据来自 View 外部时,例如在带有 SwiftUI 的 MVVM 架构中,您应该使用 @ObservedObject,您的 ViewModel 应该存储为 @ObservedObject 在你的 View.

@ObservedObjects 的一个常见错误是在 View 本身内部声明和初始化它们。这将导致问题,因为每次 @ObservedObject 发出更新(其 @Published 属性之一被更新)时,将重新创建视图 - 这也会创建一个新的 @ObservedObject,因为它是在 View 本身中初始化的。为避免此问题,无论何时使用 @ObservedObject,您总是 必须将其注入视图 。 iOS 14 @StateObject 解决了这个问题。