@ObservedObject 用于观察遵循 ObservableObject 协议的对象。当对象的某些属性标记为 @Published 并发生改变时,使用该对象的视图将自动重新渲染。
- @ObservedObject 不持有被观察的实例,不保证其生存期。
- @ObservadObject 可以在视图存续期内切换其所关联的实例。
作用:@ObservedObject用于观察引用类型对象的变化,并在对象更改时更新视图。它用于管理外部对象的状态,并在该对象发生变化时自动刷新视图。如果说 @State 是全自动驾驶的话,ObservableObject 就是半自动,它需要一些额外的声明。ObservableObject 协议要求实现类型是 class,它只有一个需要实现的属性:objectWillChange。在数据将要发生改变时,这个属性用来向外进行“广播”,它的订阅者 (一般是 View 相关的逻辑) 在收到通知后,对 View 进行刷新。
创建 ObservableObject 后,实际在 View 里使用时,我们需要将它声明为 @ObservedObject。这也是一个属性包装,它负责通过订阅 objectWillChange 这个“广播”,将具体管理数据的 ObservableObject 和当前的 View 关联起来。如果属性定义时加了@Published包装器,就可以省略objectWillChange,系统已经自动帮你实现了objectWillChange,@ObservedObject修饰的必须是遵守ObservableObject 协议的class对象,class对象的属性只有被@Published修饰时,属性的值修改时,才能被监听到
应用场景
- 通常与 @StateObject 配合使用,父视图使用 @StateObject 创建实例,子视图通过 @ObservedObject 引入该实例,响应实例变化。
- 需要动态切换实例的场景。比如在 NavigationSplitView 中,sidebar 中选择不同的实例,detail 视图动态更换数据源。
- 在视图中引入由外部框架或代码来保证存续期的 ObservableObject 实例时使用,例如引入 Core Data 的 NSManagedObject 实例。
注意事项
- 在 iOS 13中,由于没有提供
@StateObject
,此时@ObservedObject
是唯一选择,可能会因为无法保证实例的存续期而产生意想不到的结果,为了避免类似问题,可以在更高层级的视图中( 稳定性没有问题的地方 ),通过@State
来持有该实例,然后在使用的视图中通过@ObservedObject
来引入。 - 在引入第三方提供的符合 ObservableObject 实例时,应确保
@ObservedObject
引用的对象在整个视图的生命周期中都是可用的,否则可能导致运行时错误。
使用示例
class Counter: ObservableObject {
@Published var count = 0
}
struct CounterView: View {
@ObservedObject var counter = Counter()
var body: some View {
VStack {
Text("Count: \(counter.count)")
Button("Increment") {
counter.count += 1
}
}
}
}