LESSON 13 / 576 分钟
@State 与 @Binding:谁拥有状态
状态归属决定数据流。父视图拥有数据,子视图可以接收只读值或可写绑定。
用你的前端经验理解
@State 可类比 useState;@Binding 是到现有状态的读写连接,类似 value + onChange 的组合,但不是新的一份副本。
01 / 理解问题
为什么需要它
状态所有权决定谁负责创建、修改和结束一份数据的生命周期。页面是否展开、输入框当前草稿适合局部状态;全应用账号信息则通常不应在每个页面各建一份。遇到界面不同步时,先找“事实来源”,比增加更多刷新代码有效。
它是怎样工作的
@State 由 SwiftUI 按视图身份管理存储,视图描述值被重新创建并不等于状态必定丢失。@Binding 是指向已有状态的读写连接,不拥有独立副本。普通属性适合只读输入,回调适合表达动作意图。把父值复制到子 @State 后,它就成为另一份状态,后续父值更新不会自动按你的业务预期同步到草稿。
02 / 掌握要点
把关键概念连起来
1
拥有
@State 用于视图拥有的状态,框架根据视图身份维护它。普通属性适合外部传入的只读数据。
2
传递
$count 从状态生成 Binding。子视图用 @Binding 声明需要读写外部状态。
3
身份
条件分支、ForEach 的稳定 id 会影响状态存续;身份被替换时,原来的局部状态可能重置。
READ THE CODE
Swift · 示例片段
struct FavoriteToggle: View { @Binding var isFavorite: Bool var body: some View { Toggle("收藏", isOn: $isFavorite) }}- 父视图声明 @State private var isFavorite = false,然后传入 FavoriteToggle(isFavorite: $isFavorite)。
用于理解当前概念的代码片段;部分示例需要放入对应工程与作用域,并补齐上下文。
03 / 案例推演
父页面管理收藏开关
- 父页面拥有 isFavorite,通过 $isFavorite 给子控件一个 Binding。子控件切换时,父页面直接读到同一事实来源的新值。
- 如果详情需要“保存/取消”,应显式创建编辑草稿,在保存时回传,而不是绑定后又期望取消能自动撤销。
- 当列表重排时,使用稳定记录 ID 保持视图身份。每次渲染随机生成 ID 可能导致状态重置。
这里需要你亲自判断
把父视图传来的值再次保存进子视图 @State,常会制造两份不同步的数据。
04 / 动手验证
做一个小练习
在实验室点击“子视图 +1”,同时观察父状态和视图结果。
- 分别实现即时生效开关与需要保存的编辑草稿,并解释为什么二者数据流不同。
- 退出详情再进入,判断哪些状态应该恢复、哪些应重新初始化。
展开参考思路与验收标准
Binding 适合即时双向编辑,草稿适合延迟提交。@State 不是磁盘存储:应用被终止后需要恢复的业务数据仍须持久化。
05 / 检查理解
子视图要修改父视图拥有的计数,应优先用什么?
答对理解题后即可标记完成