Skip to content
swift-concurrency-6-2 logo

Swift 6.2 可接近的并发

swift-concurrency-6-2

Swift 6.2 可接近的并发性 — 默认单线程,@concurrent 用于显式后台卸载,隔离一致性用于主 actor 类型。

SKILL.md

Full skill instructions

Swift 6.2 可接近的并发

采用 Swift 6.2 并发模型的模式,其中代码默认在单线程上运行,并发是显式引入的。在无需牺牲性能的情况下消除常见的数据竞争错误。

何时启用

  • 将 Swift 5.x 或 6.0/​6.1 项目迁移到 Swift 6.2
  • 解决数据竞争安全编译器错误
  • 设计基于 MainActor 的应用架构
  • 将 CPU 密集型工作卸载到后台线程
  • 在 MainActor 隔离的类型上实现协议一致性
  • 在 Xcode 26 中启用“可接近的并发”构建设置

核心问题:隐式的后台卸载

在 Swift 6.1 及更早版本中,异步函数可能会被隐式卸载到后台线程,即使在看似安全的代码中也会导致数据竞争错误:

// Swift 6.1: ERROR
@MainActor
final class StickerModel {
    let photoProcessor = PhotoProcessor()

    func extractSticker(_ item: PhotosPickerItem) async throws -> Sticker? {
        guard let data = try await item.loadTransferable(type: Data.self) else { return nil }

        // Error: Sending 'self.photoProcessor' risks causing data races
        return await photoProcessor.extractSticker(data: data, with: item.itemIdentifier)
    }
}

Swift 6.2 修复了这个问题:异步函数默认保持在调用者所在的 actor 上。

// Swift 6.2: OK — async stays on MainActor, no data race
@MainActor
final class StickerModel {
    let photoProcessor = PhotoProcessor()

    func extractSticker(_ item: PhotosPickerItem) async throws -> Sticker? {
        guard let data = try await item.loadTransferable(type: Data.self) else { return nil }
        return await photoProcessor.extractSticker(data: data, with: item.itemIdentifier)
    }
}

核心模式 — 隔离的一致性

MainActor 类型现在可以安全地符合非隔离协议:

protocol Exportable {
    func export()
}

// Swift 6.1: ERROR — crosses into main actor-isolated code
// Swift 6.2: OK with isolated conformance
extension StickerModel: @MainActor Exportable {
    func export() {
        photoProcessor.exportAsPNG()
    }
}

编译器确保该一致性仅在主 actor 上使用:

// OK — ImageExporter is also @MainActor
@MainActor
struct ImageExporter {
    var items: [any Exportable]

    mutating func add(_ item: StickerModel) {
        items.append(item)  // Safe: same actor isolation
    }
}

// ERROR — nonisolated context can't use MainActor conformance
nonisolated struct ImageExporter {
    var items: [any Exportable]

    mutating func add(_ item: StickerModel) {
        items.append(item)  // Error: Main actor-isolated conformance cannot be used here
    }
}

核心模式 — 全局和静态变量

使用 MainActor 保护全局/静态状态:

// Swift 6.1: ERROR — non-Sendable type may have shared mutable state
final class StickerLibrary {
    static let shared: StickerLibrary = .init()  // Error
}

// Fix: Annotate with @MainActor
@MainActor
final class StickerLibrary {
    static let shared: StickerLibrary = .init()  // OK
}

MainActor 默认推断模式

Swift 6.2 引入了一种模式,默认推断 MainActor — 无需手动标注:

// With MainActor default inference enabled:
final class StickerLibrary {
    static let shared: StickerLibrary = .init()  // Implicitly @MainActor
}

final class StickerModel {
    let photoProcessor: PhotoProcessor
    var selection: [PhotosPickerItem]  // Implicitly @MainActor
}

extension StickerModel: Exportable {  // Implicitly @MainActor conformance
    func export() {
        photoProcessor.exportAsPNG()
    }
}

此模式是选择启用的,推荐用于应用、脚本和其他可执行目标。

核心模式 — 使用 @concurrent 进行后台工作

当需要真正的并行性时,使用 @concurrent 显式卸载:

重要: 此示例需要启用“可接近的并发”构建设置 — SE-0466 (MainActor 默认隔离) 和 SE-0461 (默认非隔离非发送)。启用这些设置后,extractSticker 会保持在调用者所在的 actor 上,使得可变状态的访问变得安全。如果没有这些设置,此代码存在数据竞争 — 编译器会标记它。

nonisolated final class PhotoProcessor {
    private var cachedStickers: [String: Sticker] = [:]

    func extractSticker(data: Data, with id: String) async -> Sticker {
        if let sticker = cachedStickers[id] {
            return sticker
        }

        let sticker = await Self.extractSubject(from: data)
        cachedStickers[id] = sticker
        return sticker
    }

    // Offload expensive work to concurrent thread pool
    @concurrent
    static func extractSubject(from data: Data) async -> Sticker { /​* ... */ }
}

// Callers must await
let processor = PhotoProcessor()
processedPhotos[item.id] = await processor.extractSticker(data: data, with: item.id)

要使用 @concurrent:

  1. 将包含类型标记为 nonisolated
  2. 向函数添加 @concurrent
  3. 如果函数还不是异步的,则添加 async
  4. 在调用点添加 await

关键设计决策

决策原理
默认单线程最自然的代码是无数据竞争的;并发是选择启用的
异步函数保持在调用者所在的 actor 上消除了导致数据竞争错误的隐式卸载
隔离的一致性MainActor 类型可以符合协议,而无需不安全的变通方法
@concurrent 显式选择启用后台执行是一种有意的性能选择,而非偶然
MainActor 默认推断减少了应用目标中样板化的 @MainActor 标注
选择启用采用非破坏性的迁移路径 — 逐步启用功能

迁移步骤

  1. 在 Xcode 中启用:构建设置中的 Swift Compiler > Concurrency 部分
  2. 在 SPM 中启用:在包清单中使用 SwiftSettings API
  3. 使用迁移工具:通过 swift.org/​migration 进行自动代码更改
  4. 从 MainActor 默认值开始:为应用目标启用推断模式
  5. 在需要的地方添加 @concurrent:先进行性能分析,然后卸载热点路径
  6. 彻底测试:数据竞争问题会变成编译时错误

最佳实践

  • 从 MainActor 开始 — 先编写单线程代码,稍后再优化
  • 仅对 CPU 密集型工作使用 @concurrent — 图像处理、压缩、复杂计算
  • 为主要是单线程的应用目标启用 MainActor 推断模式
  • 在卸载前进行性能分析 — 使用 Instruments 查找实际的瓶颈
  • 使用 MainActor 保护全局变量 — 全局/静态可变状态需要 actor 隔离
  • 使用隔离的一致性,而不是 nonisolated 变通方法或 @Sendable 包装器
  • 增量迁移 — 在构建设置中一次启用一个功能

应避免的反模式

  • 对每个异步函数都应用 @concurrent(大多数不需要后台执行)
  • 在不理解隔离的情况下使用 nonisolated 来抑制编译器错误
  • 当 actor 提供相同安全性时,仍保留遗留的 DispatchQueue 模式
  • 在并发相关的 Foundation Models 代码中跳过 model.availability 检查
  • 与编译器对抗 — 如果它报告数据竞争,代码就存在真正的并发问题
  • 假设所有异步代码都在后台运行(Swift 6.2 默认:保持在调用者所在的 actor 上)

何时使用

  • 所有新的 Swift 6.2+ 项目(“可接近的并发”是推荐的默认设置)
  • 将现有应用从 Swift 5.x 或 6.0/​6.1 并发迁移过来
  • 在采用 Xcode 26 期间解决数据竞争安全编译器错误
  • 构建以 MainActor 为中心的应用架构(大多数 UI 应用)
  • 性能优化 — 将特定的繁重计算卸载到后台

More skills from xu-xiang

docker-patterns logo
xu-xiang/everything-claude-code-zh

docker-patterns

用于本地开发的Docker和Docker Compose模式,包括容器安全、网络、卷策略和多服务编排。

2K 0
View
database-migrations logo
xu-xiang/everything-claude-code-zh

database-migrations

数据库迁移最佳实践,涵盖模式变更、数据迁移、回滚以及零停机部署,适用于PostgreSQL、MySQL及常用ORM(Prisma、Drizzle、Django、TypeORM、golang-migrate)。

2K 0
View
django-patterns logo
xu-xiang/everything-claude-code-zh

django-patterns

Django 架构模式、使用 DRF 的 REST API 设计、ORM 最佳实践、缓存、信号(Signals)、中间件(Middleware)以及生产级 Django 应用。

2K 0
View
foundation-models-on-device logo
xu-xiang/everything-claude-code-zh

foundation-models-on-device

苹果FoundationModels框架用于设备上的LLM——文本生成、使用@Generable进行引导生成、工具调用,以及在iOS 26+中的快照流。

2K 0
View
python-testing logo
xu-xiang/everything-claude-code-zh

python-testing

使用 pytest、TDD 方法论、固件(Fixtures)、模拟(Mocking)、参数化及覆盖率要求的 Python 测试策略。

2K 0
View
python-patterns logo
xu-xiang/everything-claude-code-zh

python-patterns

Pythonic 惯用法、PEP 8 标准、类型提示,以及构建稳健、高效且可维护 Python 应用的最佳实践。

2K 0
View
django-tdd logo
xu-xiang/everything-claude-code-zh

django-tdd

Django testing strategies with pytest-django, TDD methodology, factory_boy, mocking, coverage, and testing Django REST Framework APIs.

2K 0
View
postgres-patterns logo
xu-xiang/everything-claude-code-zh

postgres-patterns

PostgreSQL 数据库模式,涵盖查询优化、架构设计、索引和安全。基于 Supabase 最佳实践。

2K 0
View
django-verification logo
xu-xiang/everything-claude-code-zh

django-verification

Verification loop for Django projects: migrations, linting, tests with coverage, security scans, and deployment readiness checks before release or PR.

2K 0
View
deployment-patterns logo
xu-xiang/everything-claude-code-zh

deployment-patterns

部署工作流、CI/CD流水线模式、Docker容器化、健康检查、回滚策略以及Web应用程序的生产就绪检查清单。

2K 0
View
skill-stocktake logo
xu-xiang/everything-claude-code-zh

skill-stocktake

用于审计Claude技能和命令的质量。支持快速扫描(仅变更技能)和全面盘点模式,采用顺序子代理批量评估。

2K 0
View
backend-patterns logo
xu-xiang/everything-claude-code-zh

backend-patterns

后端架构模式、API 设计、数据库优化以及适用于 Node.js、Express 和 Next.js API 路由的服务端最佳实践。

2K 0
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View