窥探 `@Observable` 的“小黑盒”:private 属性到底会不会被观察?

参考原文: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+ 支持宏展开:

  1. 选中 @Observable 宏,右键选择 "Expand Macro"。
  1. 在展开的代码里搜索 @ObservationTracked:
    • 出现 = 会观察
    • 不出现 = 已忽略(或被 @ObservationIgnored 标记)

(示意:private 属性同样被 @ObservationTracked 包裹)

实战影响 & 最佳实践

场景 建议
私有缓存、临时变量 不需要观察 显式加 @ObservationIgnored
希望 SwiftUI 不刷新 的辅助属性 加 @ObservationIgnored减少调度开销
确实需要观察私有状态(如内部网络层) 保持默认即可,private 仅对外隐藏,对 Observation 透明

一句话总结

在 @Observable 世界里,"private" ≠ '忽略';

想真正跳过观察,请用 @ObservationIgnored ------ 不论 public 还是 private,编译器都会一视同仁地生成观察代码。

相关推荐
青峰讲运维2 天前
OpenStack 存储深度解析|Cinder 块存储 + Swift 对象存储原理与完整实操(Yoga)
开发语言·openstack·swift
2501_915106322 天前
Windows 上开发 Unity iOS,使用 KXBuild 进行真机调试、性能采样与打包 ipa
windows·vscode·unity·ios·个人开发·swift·敏捷流程
2501_915918413 天前
Windows 上开发 React Native iOS,真机调试、Fast Refresh 与打包 ipa
windows·vscode·react native·ios·个人开发·swift·敏捷流程
szp20054 天前
中文字幕烧进视频后整片空白:CoreText 低报行高,导出照样成功
ios·swift
2501_915106324 天前
iOS 单元测试怎么跑?用 KXApp 在 VS Code 里跑 XCTest 和 Swift Testing
ide·vscode·ios·单元测试·个人开发·swift·敏捷流程
东坡肘子4 天前
当应用不再属于特定操作系统 -- 肘子的 Swift 周报 #159
人工智能·swiftui·swift
2501_915106327 天前
Windows 用 KXBuild 开发 iOS 项目,CocoaPods、SPM 怎么处理?
windows·vscode·ios·个人开发·swift·敏捷流程·cocoapods
2501_916008898 天前
Windows 上写第一个 SwiftUI App,KXBuild 空工程起步,跑到 iPhone 真机
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程
songgeb9 天前
iOS App支持设置RTL语言的实践
ios·swift·ui kit
2501_9151063210 天前
KXApp 的 VS Code 真机调试:按下 Cmd+R 之后发生了什么
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程