@State vs @ObservableObject - 什么时候?

Ale*_*x.K 3 swift swiftui combine

我目前正在熟悉 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()
}
Run Code Online (Sandbox Code Playgroud)

所以,我错过了一点 - @State 和 @ObservedObject 方法有何不同,在哪种情况下更可取?

谢谢!

Geo*_*e_E 8

主要区别在于,@State针对结构,@ObservedObject针对类。两者@State@ObservedObject实现了类似的目标,即在发生变化时更新您的信息。

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

您在这里真正要问的问题是何时使用结构体和类(如果它们在某些情况下都可以工作)。

在您的情况下,由于TaskList只是一个基本数据结构,并且不需要您想要阻止更新视图的大量属性(通过使用/不使用@Published),因此您可能应该使用structwith@State来代替。


Dáv*_*tor 6

如果选中任何变量@State在SwiftUIView和绑定他们内部的一个属性body的是View,在body将重新计算每当@State变量的变化,因此你的整个View会重绘。此外,@State变量应该作为View. 由于这些原因,@State变量只能从bodya 中访问和更新View,因此应该声明private

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

另一方面,@ObservedObject应该用于引用类型(classes),因为它们会在任何@Published属性ObservableObject更改时触发刷新视图。

您应该使用@ObservedObject,当你有一些数据来从外部的View,如与SwiftUI的MVVM架构,您ViewModel应该存储为@ObservedObject你的View

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