@ObservedObject 是 SwiftUI 的一个属性包装器(Property Wrapper),用于在视图中订阅一个可观察对象(ObservableObject)。当这个对象发布数据变化时,SwiftUI 会自动刷新依赖它的视图。
前提条件
@ObservedObject 依赖的是 ObservableObject 协议。
任何类只要遵守 ObservableObject 并且使用 @Published 修饰属性,它的变化就会通知所有订阅它的视图。
class UserViewModel: ObservableObject {
@Published var name: String = ""
}
基本用法
父视图使用 @StateObject 创建一个实例,传入子视图。
// 父视图
struct UserRootView: View {
@StateObject var vm = UserViewModel()
var body: some View {
UserView(vm: vm)
}
}
子视图使用 @ ObservedeObject绑定传入的外部对象,并根据它的变化,自动触发视图刷新。
// 子视图
struct UserView: View {
@ObservedObject var vm: UserViewModel
var body: some View {
Toggle("性别", isOn: $vm.sex)
}
}
和@StateObject的区别
@StateObject 用于创建并持有 ViewModel,管理创建 ViewModel的生命周期。
@ObservedeObject不会创建 ViewModel,只是从接收外部传入的对象,通常用于接收对象的子视图。
它不持有对象的生命周期,只负责监听它,对象的生命周期通常由父视图 @StateObject 管理。
总结
@ObservedObject 接收从视图外部传入的ViewModel,当其发生自动刷新时,观察并刷新视图。
@ObservedObject 通常和 @StateObject 配合使用,在父视图中使用 @StateObject 创建ViewModel,在子视图中使用 @ObservedObject 接收从父视图传入的实例。
@ObservedeObject 只能用于 ObservableObject,不能直接用于SwiftData的@Model类型。
如果子视图不使用 @ObservedObject,仍然可以接受从父视图传入的对象:
struct ChildView: View {
var vm: MyViewModel // 没有 @ObservedObject
}
但是,子视图不会监听 vm 的变化。这意味着当 vm 的属性发生变化时,父视图会刷新。子视图不会直接引用 vm 并刷新视图。
但是父视图刷新时,子视图也会间接刷新,所以很多场景感觉不到区别。
如果希望子视图也能根据 vm 内部的 @Published 变化而自动刷新UI,那么就需要使用 @ObservedeObject。
相关文章
1、SwiftUI协议ObservableObject:https://fangjunyu.com/2025/11/23/swiftui%e5%8d%8f%e8%ae%aeobservableobject/
