LESSON 14 / 577 分钟

共享模型:Observation 与旧状态体系

当多处 UI 依赖同一份业务数据时,观察模型比层层复制数据更自然。

用你的前端经验理解

可以类比可观察 store 和 Context,但 SwiftUI 追踪的是视图实际访问到的可观察属性。

为什么需要它

当列表、详情和统计都展示同一批文章时,复制三份数组会制造同步问题。共享模型让业务数据具有明确所有者,Observation 让读取这些数据的界面参与更新。依赖传递与变化观察是两件事:Environment 可以把依赖送到下层,但它并不替你决定谁创建模型、何时加载数据。

它是怎样工作的

使用 Observation 的模型通常是 @Observable 类型;View 在 body 中读取可观察属性建立依赖。拥有该实例的视图可以用 @State 保持生命周期,需要生成属性绑定时使用 @Bindable。旧系统常见 ObservableObject、@Published、@StateObject 与 @ObservedObject,需要按最低系统版本和项目既有方案选择,不能只靠名称相似直接替换。

把关键概念连起来

1

现代方案

@Observable 声明可观察引用模型;视图拥有它时可用 @State,子视图需要绑定时用 @Bindable。

2

环境

@Environment 适合传递较广泛的依赖,但不要把所有局部状态塞进全局环境。

3

旧项目

ObservableObject + @Published,以及 @StateObject/@ObservedObject 仍会出现在兼容旧系统的项目中。Observation 在 iOS 17、macOS 14 等起可用。

Swift · 示例片段
import Observation@Observablefinal class LibraryModel {    var titles: [String] = []}// 拥有模型的 View 中:// @State private var model = LibraryModel()
  • @Observable 让模型属性变化可被追踪;模型实例仍需要明确的所有者,不能每次 body 计算时重新创建。
  • 关注使用位置是否读取了变化的属性。Environment 传递实例,@Bindable 在需要时提供属性绑定,职责不同。

用于理解当前概念的代码片段;部分示例需要放入对应工程与作用域,并补齐上下文。

让两个页面共享收藏数量

  1. 在明确的应用或功能入口创建一个 LibraryModel,把同一实例传给列表和统计页面。
  2. 列表动作修改模型中的收藏状态,统计页面读取模型计算的数量。避免维护另一份手动更新的 favoriteCount。
  3. 预览时注入独立模型,填入少量数据,防止预览操作污染真实磁盘或网络。

这里需要你亲自判断

不要混用两套 API 后指望所有属性自动刷新;先看项目最低系统版本和模型定义方式。

做一个小练习

用一个共享阅读清单模型,让列表页和统计页读取同一份数据。

  1. 画出模型创建位置以及两个消费者,检查有没有意外执行两次初始化。
  2. 修改一篇文章的收藏状态,确认列表、详情和总数一致。
展开参考思路与验收标准

应只有一个预期的共享实例,统计结果从源数据派生。模型内部某个非可观察引用对象自行变化,不一定产生你期待的更新;需要检查实际观察链,而不是盲目添加 objectWillChange。

@Bindable 的主要作用是什么?

继续查阅官方资料
Apple Developer 官方资料管理应用模型数据

本课聚焦核心认知。具体 API、系统要求与发布政策,以当前官方文档和工程验证为准。

答对理解题后即可标记完成