0Pricing
Swift Academy · 课时

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 反馈 — 无需本地设置。

此课程中的所有课时

  1. 理解视图身份
  2. 减少主体重新求值
  3. Equatable 视图与 @State 作用域
  4. 使用 SwiftUI Instrument 进行性能分析
← 返回 Swift Academy