@Observable (iOS 17+) vs ObservableObject 对比

基于宏的现代 Swift 观察机制

VS
ObservableObject

经典的基于 Combine 的观察机制(iOS 13+)

8 分钟阅读iOS

评分对比

图表加载中…

详细评分

详细评分: @Observable (iOS 17+) ObservableObject ——按类别打分,满分 10 分
分类@Observable (iOS 17+)ObservableObject
性能
10/10
7/10
学习难易度
9/10
8/10
生态系统
9/10
10/10
社区
8/10
10/10
就业市场
9/10
8/10
面向未来
10/10
7/10

优缺点

@Observable (iOS 17+)

优点

  • 仅当被读取的属性发生变化时才触发重渲染(细粒度)
  • 无需 @Published 语法
  • 嵌套对象自动被观察
  • 在大型视图中性能提升 40%-60%
  • 宏在编译期提供安全性保障
  • 通过 @Bindable 实现双向绑定
  • 兼容 Combine(objectWillChange 依然可用)
  • 语法更简洁

缺点

  • 仅支持 iOS 17+(iOS 16 以下需回退至 ObservableObject)
  • 宏调试略有难度
  • 添加类似 KVO 的自定义观察者较为复杂
  • 部分 Combine 模式需要迁移调整

最适合

仅面向 iOS 17+ 的应用新的 SwiftUI 项目对性能要求高的列表/网格视图深层嵌套状态结合现代 Swift 并发使用

ObservableObject

优点

  • 广泛支持 iOS 13+
  • 经过 5 年生产环境验证
  • 与 Combine 框架深度集成
  • 可通过 objectWillChange.send() 手动控制
  • 支持 @Published + CurrentValueSubject 模式
  • 兼容小组件与扩展(Widget + Extension)
  • 测试模式已相当成熟
  • 拥有大量社区代码可供参考

缺点

  • 每次 @Published 变化都会触发整个视图重渲染
  • 嵌套可观察对象处理较困难
  • 语法较为冗长
  • 在大型视图中性能较低

最适合

需要支持 iOS 13-16 的应用重度依赖 Combine 的架构已有的 ObservableObject 代码库Widget + ShareExtension 场景企业级遗留项目

代码对比

@Observable (iOS 17+)
import SwiftUI
import Observation

@Observable
class UserStore {
    var user: User?
    var isLoading = false

    func fetchUser() async {
        isLoading = true
        user = try? await api.getUser()
        isLoading = false
    }
}

struct UserView: View {
    @Bindable var store: UserStore

    var body: some View {
        TextField("Name", text: $store.user.name ?? .constant(""))
    }
}
ObservableObject
import SwiftUI
import Combine

class UserStore: ObservableObject {
    @Published var user: User?
    @Published var isLoading = false

    func fetchUser() async {
        await MainActor.run { isLoading = true }
        let fetched = try? await api.getUser()
        await MainActor.run {
            user = fetched
            isLoading = false
        }
    }
}

结论

面向 iOS 17+ 的项目 → 必须使用 @Observable(性能更优、面向未来)。若需支持 iOS 16,可使用 @Observable 配合 #if available,回退到 ObservableObject。到 2026 年,新写 ObservableObject 代码已属于反模式。

获取免费咨询
常见问题

常见问题

不大。移除 @Published,为类添加 @Observable,移除 ObservableObject 协议。@ObservedObject → @Bindable。每个 store 通常只需 10-20 分钟。

相关博客文章

查看全部文章

相关项目

查看全部项目
全部对比