关于SwiftUI中嵌套@Observable类型是否触发视图更新的技术问询
SwiftUI中嵌套@Observable类型是否会触发视图更新?
你测试得到的结果是完全正确的——点击"update nested model value"按钮时,对应的Text(model.nestedModel.value)确实会自动更新,这并不是什么边缘情况,而是@Observable宏的原生设计能力。
为什么这个场景会生效?
@Observable的核心是细粒度的依赖追踪,和旧的ObservedObject有本质区别:
- 当你的视图
body中访问model.nestedModel.value时,SwiftUI的依赖系统会自动拆解这个访问路径:它不仅会记录当前视图依赖MainModel的nestedModel属性,还会进一步记录依赖NestedModel的value属性。 - 当你调用
model.nestedModel.updateValue()修改value时,@Observable生成的底层逻辑会发送属性变更通知,SwiftUI检测到这个被依赖的属性发生变化,就会自动触发视图重绘。
为什么之前查资料没找到明确说明?
WWDC23的演讲和官方文档更多侧重@Observable的基础用法,嵌套场景其实是它细粒度追踪能力的自然延伸,所以没有单独拿出来做重点强调。而旧的ObservedObject需要显式在视图中声明@ObservedObject才能追踪嵌套对象的变更,这可能让你形成了"嵌套需要额外处理"的固有印象,但@Observable的设计就是为了简化这种场景。
对比旧的ObservedObject写法
如果用旧的ObservedObject实现相同逻辑,你需要在视图中额外声明@ObservedObject var nestedModel: NestedModel,或者在MainModel中手动发送objectWillChange通知,但@Observable完全不需要这些额外操作,依赖追踪是自动完成的。
补充验证小技巧
你可以在NestedObservableView的body里加一行打印代码,直观验证视图的重绘时机:
struct NestedObservableView: View { var model: MainModel var body: some View { print("视图重绘了") // 新增打印代码 VStack { // 原有视图代码... } } }
点击两个按钮时都会看到打印日志,说明不管是修改MainModel的属性,还是修改嵌套的NestedModel的属性,只要视图中直接访问了对应的属性,就会触发更新。
内容来源于stack exchange
相关产品推荐
相关产品推荐

