Equatable 视图与 @State 作用域
缩小状态范围,以限制失效传播。
Equatable 视图与 @State 作用域 是 CoddyKit 上的免费 Swift Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Swift Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Swift Academy 课程共包含 4 节课。
相等性可以省去不必要的工作
如果 SwiftUI 能证明视图的输入没有变化,就可以跳过对它的重新渲染。让视图遵循 Equatable,可以为 SwiftUI 提供一种精确的判断方式。
遵循 Equatable
让您的视图遵循 Equatable,SwiftUI 就会比较新旧值。如果两者相等,就会跳过主体。
struct Badge: View, Equatable {
let count: Int
var body: some View { Text("\(count)") }
static func == (a: Badge, b: Badge) -> Bool {
a.count == b.count
}
}EquatableView
您还可以使用 .equatable() 包装任意 Equatable 视图,从而请求基于比较来跳过更新,而无需修改各处的类型调用位置。
Badge(count: total)
.equatable()Equatable 何时有帮助
对于输入易于比较但主体执行成本很高的视图,Equatable 尤其有效。比较成本必须远低于渲染成本,这种做法才值得。
比较成本陷阱
如果您的 == 本身就很耗时(例如比较大型数组的深层内容),它的成本可能高于您试图跳过的渲染。请只比较成本低且能明确作出判断的字段。
static func == (a: Self, b: Self) -> Bool {
a.id == b.id && a.version == b.version // cheap fields
}默认自动合成 Equatable
如果所有存储属性都遵循 Equatable,Swift 可以自动合成 ==。但闭包和某些类型并不遵循 Equatable,因此您可能需要自定义实现并忽略这些属性。
struct Card: View, Equatable {
let title: String
let onTap: () -> Void // not Equatable
static func == (a: Card, b: Card) -> Bool { a.title == b.title }
var body: some View { Text(title) }
}缩小 @State 作用域
状态放置得太高,会导致其下方的所有内容重新渲染。将 @State 下移到拥有它的最小视图中,使变化影响尽可能少的界面。
// Move toggle state into the row that uses it
struct Row: View {
@State private var expanded = false
var body: some View { /* only this row re-renders */ Text("Row") }
}仅在需要共享时提升状态
只有在多个视图确实需要某个状态时,才将它提升到更高层。否则,使用本地状态可以让重新渲染的影响范围保持较小。
提取子视图以局部化更新
将频繁变化的部分提取为独立视图,可以把重新评估限制在该视图内,而不会影响其同级视图。
struct LiveClock: View {
@State private var now = Date()
var body: some View { Text(now, style: .time) }
}绑定与作用域
@Binding 将子视图连接到父视图的状态。传递范围更窄的绑定(例如单个字段),而不是整个对象,可以限制哪些变化会向下传播。
struct NameField: View {
@Binding var name: String // narrow binding
var body: some View { TextField("Name", text: $name) }
}结合 Equatable 与作用域
结合多种技术可以获得最佳效果:缩小状态的放置范围以减少触发源,再使用 Equatable 跳过仍然触发的重新渲染。
快速检查:Equatable 视图
测试您对 Equatable 视图和状态作用域的理解。
回顾:Equatable 视图与状态作用域
让视图遵循 Equatable(或使用 .equatable())可以让 SwiftUI 跳过没有变化的渲染;只有在比较成本远低于渲染成本,并且只比较关键字段时,这样做才有价值。
将 @State 缩小到拥有它的最小视图,传递范围更窄的绑定,并将易变部分提取为独立视图。将紧凑的状态作用域与 Equatable 结合,可以实现次数最少、成本最低的重新渲染。
常见问题解答
「Equatable 视图与 @State 作用域」课时是免费的吗?
是的 — 「Equatable 视图与 @State 作用域」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Swift Academy 课程的其余内容,请升级到 CoddyKit PRO。 Swift Academy 课程共包含 4 节课。
「Equatable 视图与 @State 作用域」这节课中我会学到什么?
缩小状态范围,以限制失效传播。 你通过在浏览器中直接运行的动手代码来练习 Swift Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Swift Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Swift Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「Equatable 视图与 @State 作用域」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Swift Academy 课中编写并运行代码吗?
能。每节 Swift Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 理解视图身份
- 减少主体重新求值
- Equatable 视图与 @State 作用域
- 使用 SwiftUI Instrument 进行性能分析