modern-swift

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Modern Swift (6.2+)

现代Swift(6.2+)

Swift 6.2 introduces strict compile-time concurrency checking with async/await, actors, and Sendable constraints that prevent data races at compile time instead of runtime. This is the foundation of safe concurrent Swift.
Swift 6.2引入了基于async/await、actors和Sendable约束的严格编译期并发检查,可在编译阶段而非运行时防止数据竞争。这是Swift安全并发的基础。

Overview

概述

Modern Swift replaces older concurrency patterns (completion handlers, DispatchQueue, locks) with compiler-enforced safety. The core principle: if it compiles with strict concurrency enabled, it cannot have data races.
现代Swift用编译器强制的安全机制取代了旧的并发模式(完成处理程序、DispatchQueue、锁)。核心原则:在启用严格并发检查的情况下能编译通过的代码,不会存在数据竞争。

Quick Reference

快速参考

NeedUseNOT
Async operation
async/await
Completion handlers
Main thread work
@MainActor
DispatchQueue.main
Shared mutable state
actor
Locks, serial queues
Parallel tasks
TaskGroup
DispatchGroup
Thread safety
Sendable
@unchecked
everywhere
需求推荐用法不推荐用法
异步操作
async/await
完成处理程序
主线程任务
@MainActor
DispatchQueue.main
可变共享状态
actor
锁、串行队列
并行任务
TaskGroup
DispatchGroup
线程安全
Sendable
到处使用
@unchecked

Core Workflow

核心工作流程

When writing async Swift code:
  1. Mark async functions with
    async
    , call with
    await
  2. Apply
    @MainActor
    to view models and UI-updating code
  3. Use
    actor
    instead of locks for shared mutable state
  4. Check
    Task.isCancelled
    or call
    Task.checkCancellation()
    in loops
  5. Enable strict concurrency in Package.swift for compile-time safety
编写异步Swift代码时:
  1. async
    标记异步函数,调用时使用
    await
  2. 为视图模型和UI更新代码添加
    @MainActor
  3. 使用
    actor
    而非锁来管理可变共享状态
  4. 在循环中检查
    Task.isCancelled
    或调用
    Task.checkCancellation()
  5. 在Package.swift中启用严格并发检查以获得编译期安全保障

Reference Loading Guide

参考资料加载指南

ALWAYS load reference files if there is even a small chance the content may be required. It's better to have the context than to miss a pattern or make a mistake.
ReferenceLoad When
Concurrency EssentialsWriting async code, converting completion handlers, using
await
Swift 6 ConcurrencyUsing
@concurrent
,
nonisolated(unsafe)
, or actor patterns
Task GroupsRunning multiple async operations in parallel
Task CancellationImplementing long-running or cancellable operations
Strict ConcurrencyEnabling Swift 6 strict mode or fixing Sendable errors
MacrosUsing or understanding Swift macros like
@Observable
Modern AttributesMigrating legacy code or using
@preconcurrency
,
@backDeployed
Migration PatternsModernizing delegate patterns or UIKit views
只要有哪怕一丝可能需要用到相关内容,就一定要加载参考文件。 拥有上下文总比遗漏模式或犯错要好。
参考资料加载场景
并发基础编写异步代码、转换完成处理程序、使用
await
Swift 6并发使用
@concurrent
nonisolated(unsafe)
或actor模式时
任务组并行运行多个异步操作时
任务取消实现长时间运行或可取消的操作时
严格并发启用Swift 6严格模式或修复Sendable错误时
使用或理解Swift宏(如
@Observable
)时
现代属性迁移遗留代码或使用
@preconcurrency
@backDeployed
迁移模式现代化委托模式或UIKit视图时

Common Mistakes

常见错误

  1. @unchecked Sendable
    as a quick fix
    — Using
    @unchecked Sendable
    to silence compiler errors means you've opted out of safety. If the error persists after
    @unchecked
    , your code has a potential data race. Fix the underlying issue instead.
  2. Missing
    await
    at call sites
    — Forgetting
    await
    when calling async functions is a compiler error, but checking
    Task.isCancelled
    in a loop without calling
    Task.checkCancellation()
    silently ignores cancellation.
  3. Capturing
    self
    in async blocks without
    weak
    — Holding a strong reference to
    self
    in a long-running async task prevents deinit. Always use
    [weak self]
    in closures or use
    .task
    which auto-manages the lifecycle.
  4. Not checking task cancellation — Long-running operations should regularly check
    Task.isCancelled
    or call
    Task.checkCancellation()
    , otherwise cancellation signals are ignored.
  5. Forgetting
    @MainActor
    on UI code and test suites
    — Main test struct and view models that update
    @Published
    properties need
    @MainActor
    . Forgetting it silently allows cross-thread mutations. Apply
    @MainActor
    to: view models, view structs, main test structs, and any type that touches UI.
  6. Actor re-entrancy surprises
    await
    inside an actor method can release the lock temporarily. Another task may modify actor state. Design actor methods assuming state can change between
    await
    points.
  1. @unchecked Sendable
    快速解决问题
    —— 使用
    @unchecked Sendable
    来掩盖编译器错误意味着你主动放弃了安全保障。如果添加
    @unchecked
    后错误仍然存在,说明你的代码存在潜在的数据竞争。应修复根本问题而非掩盖错误。
  2. 调用异步函数时遗漏
    await
    —— 调用异步函数时忘记写
    await
    会触发编译器错误,但在循环中仅检查
    Task.isCancelled
    却不调用
    Task.checkCancellation()
    会悄悄忽略取消信号。
  3. 在异步块中捕获
    self
    时未使用
    weak
    —— 在长时间运行的异步任务中强引用
    self
    会阻止对象被销毁。在闭包中务必使用
    [weak self]
    ,或使用
    .task
    来自动管理生命周期。
  4. 未检查任务取消状态 —— 长时间运行的操作应定期检查
    Task.isCancelled
    或调用
    Task.checkCancellation()
    ,否则取消信号会被忽略。
  5. UI代码和测试套件遗漏
    @MainActor
    —— 更新
    @Published
    属性的主测试结构体和视图模型需要添加
    @MainActor
    。遗漏该属性会悄悄允许跨线程修改。请为以下类型添加
    @MainActor
    :视图模型、视图结构体、主测试结构体以及任何涉及UI的类型。
  6. Actor重入意外 —— Actor方法内部的
    await
    会临时释放锁。其他任务可能会修改Actor的状态。设计Actor方法时,要假设
    await
    点之间的状态可能发生变化。