参考原文:Exploring Observation in Swift: What Happens with Private Properties
问题抛出
swift
import Observation
@Observable
final class ViewModel {
var publicProp = "A" // 1️⃣ 公开,可观察
@ObservationIgnored var ignoredProp = "B" // 2️⃣ 显式忽略
private var privateProp = "C" // 3️⃣ 私有,会参与观察吗?
}
- 直觉:private = 对外隐藏 = 不生成观察代码?
- 真相:除非加
@ObservationIgnored
,否则一律观察,与可见性无关!
验证工具:SIL(Swift Intermediate Language)
一键导出 SIL
bash
xcrun swiftc -emit-silgen -Onone -parse-as-library \
-sdk $(xcrun --show-sdk-path --sdk macosx) \
ViewModel.swift > ViewModel.sil
导出后的文件我存储在了:gitcode.com/unravel/dis...
关键发现(节选)
属性 | 是否生成 _modify 调用方法 |
结论 |
---|---|---|
publicProp | ✅ 有 | 参与观察 |
ignoredProp | ❌ 无 | 直接读写,无开销 |
privateProp | ✅ 有 | 同样被观察 |
可见:编译器为 所有非忽略属性 生成相同的观察包装,private 也不能幸免。
Xcode 可视化捷径:Expand Macro
不想看 SIL?Xcode 15+ 支持宏展开:
- 选中
@Observable
宏,右键选择 "Expand Macro"。

- 在展开的代码里搜索
@ObservationTracked
:- 出现 = 会观察
- 不出现 = 已忽略(或被
@ObservationIgnored
标记)
(示意:private 属性同样被 @ObservationTracked
包裹)

实战影响 & 最佳实践
场景 | 建议 |
---|---|
私有缓存、临时变量 不需要观察 | 显式加 @ObservationIgnored |
希望 SwiftUI 不刷新 的辅助属性 | 加 @ObservationIgnored 减少调度开销 |
确实需要观察私有状态(如内部网络层) | 保持默认即可,private 仅对外隐藏,对 Observation 透明 |
一句话总结
在
@Observable
世界里,"private" ≠ '忽略';
想真正跳过观察,请用 @ObservationIgnored
------ 不论 public 还是 private,编译器都会一视同仁地生成观察代码。