Swift中@Observable宏与Observable协议的区别及功能等价性分析
Swift中@Observable宏与Observable协议的区别及功能对比
两者功能不等价,@Observable是为简化Observable协议实现而生的语法糖,手动遵循Observable协议则能提供极致自定义能力,但开发成本更高。具体区别如下:
1. 实现逻辑差异
@Observable宏:
编译器会自动生成Observable协议的全部必要实现,包括:- 自动追踪类内所有存储属性的变化
- 属性修改时自动向订阅者发送变更通知
- 处理订阅、取消订阅的底层逻辑
你只需用@Observable标记类,所有存储属性默认就具备可观察性,无需额外代码。
示例代码:
@Observable class MyClass { var username: String = "guest" var score: Int = 0 // 无需手动添加任何观察相关代码 }手动遵循Observable协议:
必须自行实现协议要求的所有逻辑,包括:- 管理订阅者集合
- 属性变更时主动触发通知
- 处理订阅的生命周期(如取消订阅)
这种方式完全由你掌控观察逻辑,但需要编写大量底层代码,复杂度高。
简化版示例代码:
class MyClass: Observable { var username: String = "guest" { willSet { notifySubscribers(\.username, oldValue: username, newValue: newValue) } } var score: Int = 0 { willSet { notifySubscribers(\.score, oldValue: score, newValue: newValue) } } // 手动实现订阅逻辑 private var subscribers: [AnyHashable: ((Any, Any) -> Void)] = [:] func subscribe<Subject: Observable, Value>(to keyPath: KeyPath<Subject, Value>, on queue: DispatchQueue?, _ handler: @escaping (Value, Value) -> Void) -> AnyCancellable { let id = UUID() subscribers[id] = { old, new in handler(old as! Value, new as! Value) } return AnyCancellable { [weak self] in self?.subscribers.removeValue(forKey: id) } } private func notifySubscribers<Value>(_ keyPath: KeyPath<MyClass, Value>, oldValue: Value, newValue: Value) { subscribers.values.forEach { handler in handler(oldValue, newValue) } } }
2. 使用场景差异
- @Observable宏:适配绝大多数日常开发场景,比如SwiftUI视图状态管理,快速创建可观察对象,代码简洁易维护,无需关心底层细节。
- 手动遵循Observable协议:仅在需要高度自定义观察逻辑时使用,比如:
- 控制特定属性是否可观察(而非全部属性)
- 自定义变更通知的时机或调度队列
- 集成自定义事件系统
3. 功能覆盖度
@Observable宏自动实现的逻辑已经覆盖了绝大多数常见观察需求,普通开发者用@Observable完全足够。手动遵循协议虽能实现更多自定义,但日常开发中极少需要——宏已经封装了最优的默认实现。
内容的提问来源于stack exchange,提问作者Stoic
相关产品推荐
相关产品推荐

