探索 SwiftUI 中的并发机制
探究 SwiftUI 如何利用 Swift 并发机制来构建安全且响应灵敏的 App。SwiftUI 默认使用主 Actor 并将工作转移给其他 Actor,同时通过并发注解和事件循环来管理异步任务,以实现流畅的动画和 UI 更新,并帮助开发者避免数据争用。
简介
SwiftUI 利用 Swift 并发来帮助开发者构建快速且无数据争用的 App。Swift 6.2 引入了一种新的语言模式,该模式会隐式为模块中的所有类型添加 @MainActor 注释。SwiftUI 会以多种方式并发运行代码,并通过其 API 提供并发注释,以帮助开发者识别和管理并发。本次讲座将重点讲解 SwiftUI 如何处理并发以避免数据争用并提升 App 性能。
主 Actor 牧场
由于 SwiftUI 的 View 协议被 @MainActor 隔离,这使得这种隔离行为成为 UI 代码的编译时默认设置。这意味着大多数 UI 代码在主线程上隐式运行,从而简化了开发流程并确保与 UIKit 和 AppKit 的兼容性。View 中实例化的数据模型也会自动隔离。SwiftUI 的 @MainActor 注释反映的是其运行时行为和预期语义,而不仅仅是编译时的便利性。
并发山峰
SwiftUI 使用后台线程执行计算密集型任务,如动画和形状计算(例如:“Shape”协议的“path”方法、“visualEffect”闭包、“Layout”协议、“onGeometryChange”闭包),以避免 UI 卡顿。在主 Actor 和后台线程之间共享数据时,“Sendable”注释会指示潜在的数据争用情况。为避免数据争用,请尽量减少数据共享。如果确实需要共享,应创建数据副本。
代码营地
SwiftUI 的动作回调在设计上是同步的,以确保 UI 能够立即更新,尤其是针对动画和载入状态等场景。长时间运行的任务应异步启动,但 UI 更新仍应保持同步。可将 UI 逻辑与非 UI(异步)逻辑区分开来,并使用状态作为桥梁,从而在异步任务完成后触发 UI 更新。保持视图中的异步代码简洁明了,并专注于将 UI 事件传达给模型。时间敏感的逻辑要求 SwiftUI 的输入和输出保持同步。
后续步骤
Swift 6.2 提供了出色的默认 Actor 隔离设置。如果你已有 App,不妨尝试一下。你将能够删除大多数 @MainActor 注释。Mutex 是使类可发送的重要工具。请查看官方文档了解具体方法。挑战自己,为 App 中的异步代码编写一些单元测试。看看你是否可以在不导入 SwiftUI 的情况下完成编写。