@StateObject 用于创建并持有 ObservableObject 对象,确保其生命周期与视图相同。
- @StateObject 专门用于管理符合 ObservableObject 协议的实例。
- 标注的对象实例在视图的整个生命周期中保持唯一,即使视图更新,对象实例也不会重新创建。
作用:@StateObject 用于在视图中创建一个持久化的可观察对象,专门用于管理符合 ObservableObject 协议的实例,并在视图的生命周期内保持持久性。它类似于@ObservedObject,但在对象生命周期中只会创建一次,标注的对象实例在视图的整个生命周期中保持唯一,即使视图更新,对象实例也不会重新创建。
应用场景
-
@StateObject
通常在视图树中最顶层使用,用于创建和维护 ObservableObject 实例。 - 常用于需要在视图的整个生命周期中持续存在的数据模型或业务逻辑。
- 相较
@State
而言,@StateObject
更适合管理复杂的数据模型及其执行逻辑
注意事项
-
@StateObject
触发视图更新的条件包括使用@Published
标注的属性被赋值和调用objectWillChange
发布者。 - 只在必须响应实例属性变化的视图中使用
@StateObject
,如果仅需读取数据而不需要观察变化,可考虑其他选项。 - 引入
@StateObject
意味着所有相关操作都在主线程上进行( SwiftUI 会隐式为视图添加@MainActor
),包括异步操作。应将需要在非主线程上运行的代码应该从视图代码中剥离。 - 如果在视图存续期有保障的地方创建实例( 比如说 App 层级),且在当前层级也无需响应该实例中属性的变化,可以不使用 @StateObject。
使用示例
class TimerData: ObservableObject {
@Published var timeCount = 0
}
struct TimerView: View {
@StateObject var timer = TimerData()
var body: some View {
Text("Time: \(timer.timeCount)")
}
}
在下面的示例中,我们创建一个 DataModel 类,并使用 @StateObject 在视图中创建和使用该对象
class DataModel: ObservableObject {
@Published var data: [String] = []
}
struct ContentView: View {
@StateObject var dataModel = DataModel()
var body: some View {
VStack {
Button(action: {
dataModel.data.append("New Item")
}) {
Text("Add Item")
}
ForEach(dataModel.data, id: \.self) { item in
Text(item)
}
}
}
}
@StateObject和@ObservedObject区别:
@SateObject针对引用类型设计,被View持有,当View更新时,实例不会被销毁,与State类似,使得View本身拥有数据,这使得 @StateObject 适用于那些需要持久状态且与视图密切相关的数据对象,比如页面导航、用户输入等。@StateObject告诉SwiftUI,当这个视图更新时,你希望保留这个对象的一个示例
@ObservedObject只是作为View的数据依赖,不被View持有,View更新时ObservedObject对象可能会被销毁,适合数据在SwiftUI外部存储,把@ObservedObject包裹的数据作为视图的依赖,比如数据库中存储的数据,当SwiftUI视图“更新”时,实际发生的是创建并显示视图的新示例。
这意味着当您通过@ObservableObject声明视图模型时,您将获得数据对象Model的一个新示例。
网友评论