SwiftUI:为何@Observable对象无关属性变更时会重建视图?
问题原因及解决方法
你的问题核心在于SwiftUI无法精确追踪非Observable引用类型的内部属性变化,导致无关视图被连带重建。
具体原因
你给Book标记了@Observable,但Page只是普通类,没有启用Observable追踪:
- 当修改
book.pageOne.isAvailable时,Book的pageOne属性本身并没有改变(还是同一个Page实例的引用),理论上Book不会触发全局变化通知。 - 但在
ChangeView中,你既用book.pageOne.isAvailable生成Toggle标题,又通过@Bindable绑定了该属性。由于Page不是Observable,SwiftUI无法精准识别你只依赖isAvailable这一个子属性,只能把整个Book对象作为ChangeView的依赖项。 - 当
isAvailable变化时,SwiftUI会判定Book发生了变化,触发父视图ContentView的body重建,进而导致它的所有子视图(包括不关心isAvailable的DisplayView)都被重新创建。
解决方法
给Page也加上@Observable标记,让SwiftUI可以精准追踪它的内部属性变化:
@Observable class Page { var pageTitle = "pageTitle" var isAvailable = true }
修改后,当你点击Toggle改变isAvailable时,只有依赖该属性的ChangeView会重建,DisplayView因为只绑定pageTitle,只要这个属性不变,就不会被重建。
补充说明
SwiftUI的视图重建本身开销很小,大部分情况下不用过度担心,但精准的依赖追踪能让视图更新更高效,也符合你预期的"只更新关心变化的视图"的行为。
内容的提问来源于stack exchange,提问作者LittleExp
相关产品推荐
相关产品推荐

