You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 17:42:17