迁移ObservableObject至@Observable宏:未标记@ObservationIgnored的影响
关于@Observable宏中未标记@ObservationIgnored的非发布属性问题解答
核心行为说明
先明确@Observable宏的核心逻辑:它会自动为类中所有未标记@ObservationIgnored的属性生成完整的观察代码——包括添加属性变更钩子、维护观察者集合、触发变更通知等逻辑。针对你的问题,具体解答如下:
1. 不标记@ObservationIgnored会引发的问题
- 性能/功耗损耗:
即便没有任何观察者监听该属性,每次修改属性时,@Observable生成的代码仍会执行「检查观察者集合是否为空」「准备变更通知」等额外操作。如果该属性是高频更新类型(比如动画帧数据、循环内频繁修改的变量),这些累积的微小开销会逐渐消耗CPU资源,进而增加设备功耗。 - 潜在引用风险:
虽然@Observable对观察者采用弱引用存储,但如果属性被默认纳入观察体系,可能会间接触发一些不必要的观察者注册逻辑(比如第三方库或自定义代码误监听该属性),进而引发意外的对象引用持有,提升内存泄漏的潜在风险。
2. 无观察者时标记与不标记的性能差异
- 如果属性极少被修改:两者性能差异几乎可以忽略,因为单次检查观察者的开销微乎其微。
- 如果属性频繁被修改:@ObservationIgnored会直接跳过所有观察相关逻辑(包括willSet/didSet里的通知检查),直接修改属性值,此时性能差异会明显体现——尤其是在大量循环、实时计算等场景下,能减少不必要的CPU消耗。
示例代码对比
原ObservableObject实现中,b是普通属性,不会触发任何变更通知逻辑:
class Class1: ObservableObject { @Published var a: Int = 1 var b: Int = 2 // 无观察逻辑 }
新@Observable实现中,若不给b加@ObservationIgnored,它会被默认处理为可观察属性:
@Observable class Class2 { var a: Int = 1 // 自动生成观察逻辑,等价于原@Published var b: Int = 2 // 默认生成观察逻辑,若不需要需标记@ObservationIgnored }
如果希望b保持原普通属性的行为,建议添加@ObservationIgnored,完全匹配原代码的性能和行为:
@Observable class Class2 { var a: Int = 1 @ObservationIgnored var b: Int = 2 // 恢复为无观察逻辑的普通属性 }
内容的提问来源于stack exchange,提问作者S.Kr
相关产品推荐
相关产品推荐

