Communitygithub.com

swift-concurrency-6-2

Swift 6.2 平易近人的并发模型——默认单线程,通过 @concurrent 显式后台卸载,为主 actor 类型提供隔离实现。适用于采用 Swift 6.2 并发模型时,通过 @concurrent 卸载任务或解决主 actor 隔离问题。

swift-concurrency-6-2 是什么?

该技能专注于 Swift 6.2 的新并发模型,其核心理念是“默认单线程,并发显式化”。它解决了之前 Swift 版本中 `async` 函数可能隐式卸载到后台线程导致的数据竞争问题,通过让 `async` 函数默认留在调用 actor 上,从根本上消除了常见的数据竞争错误。skill 详细介绍了三个核心模式:隔离实现(`@MainActor` 类型可安全地遵循非隔离协议)、全局/静态变量的 actor 隔离、以及使用 `@concurrent` 显式地将 CPU 密集型工作卸载到后台。它还支持主 actor 默认推断模式,可减少大量的 `@MainActor` 注解。此技能适用于 Xcode 26 中采用 Swift 6.2 项目、从 Swift 5.x 或 6.0/6.1 迁移的应用、以及需要解决数据竞争编译器错误的场景。它提供了清晰的迁移步骤、最佳实践和反模式,帮助开发者平稳、安全地过渡到更健壮的并发模型。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/everything-claude-code/tree/main/skills/swift-concurrency-6-2

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

Swift 6.2 平易近人的并发模型

采用 Swift 6.2 并发模型的模式,代码默认单线程运行,并发通过显式方式引入。无需牺牲性能即可消除常见的数据竞争错误。

何时激活

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

核心问题:隐式后台卸载

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

// Swift 6.1: 错误
@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 }

        // 错误:发送 'self.photoProcessor' 有导致数据竞争的风险
        return await photoProcessor.extractSticker(data: data, with: item.itemIdentifier)
    }
}

Swift 6.2 修复了这个问题:async 函数默认停留在调用 actor 上。

// Swift 6.2: 正确 — async 停留在 MainActor 上,无数据竞争
@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: 错误 — 跨越进入主 actor 隔离代码
// Swift 6.2: 正确,使用隔离实现
extension StickerModel: @MainActor Exportable {
    func export() {
        photoProcessor.exportAsPNG()
    }
}

编译器确保该实现仅在主 actor 上使用:

// 正确 — ImageExporter 也是 @MainActor
@MainActor
struct ImageExporter {
    var items: [any Exportable]

    mutating func add(_ item: StickerModel) {
        items.append(item)  // 安全:相同的 actor 隔离
    }
}

// 错误 — 非隔离上下文不能使用 MainActor 实现
nonisolated struct ImageExporter {
    var items: [any Exportable]

    mutating func add(_ item: StickerModel) {
        items.append(item)  // 错误:此处无法使用 MainActor 隔离的实现
    }
}

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

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

// Swift 6.1: 错误 — 非 Sendable 类型可能具有共享可变状态
final class StickerLibrary {
    static let shared: StickerLibrary = .init()  // 错误
}

// 修复:使用 @MainActor 注解
@MainActor
final class StickerLibrary {
    static let shared: StickerLibrary = .init()  // 正确
}

主 Actor 默认推断模式

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

// 启用 MainActor 默认推断后:
final class StickerLibrary {
    static let shared: StickerLibrary = .init()  // 隐式 @MainActor
}

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

extension StickerModel: Exportable {  // 隐式 @MainActor 实现
    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
    }

    // 将昂贵的工作卸载到并发线程池
    @concurrent
    static func extractSubject(from data: Data) async -> Sticker { /* ... */ }
}

// 调用者必须使用 await
let processor = PhotoProcessor()
processedPhotos[item.id] = await processor.extractSticker(data: data, with: item.id)

使用 @concurrent:

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

关键设计决策

决策理由
默认单线程大多数自然代码无数据竞争;并发是可选加入的
async 停留在调用 actor 上消除了导致数据竞争错误的隐式卸载
隔离实现MainActor 类型可以遵循协议,无需不安全的变通方法
@concurrent 显式加入后台执行是审慎的性能选择,而非偶然
MainActor 默认推断减少应用目标的 @MainActor 样板注解
可选加入非破坏性迁移路径 — 增量启用功能

迁移步骤

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

最佳实践

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

应避免的反模式

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

使用时机

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

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/claude-api

Anthropic Claude API patterns for Python and TypeScript. Covers Messages API, streaming, tool use, vision, extended thinking, batches, prompt caching, and Claude Agent SDK. Use when building applications with the Claude API or Anthropic SDKs.

affaan-m/everything-claude-code

End-to-end marketing campaign planning and execution. Covers audience research, positioning, campaign angle definition, landing page copy, email sequences, social posts, ad copy, short-form video scripts, and content calendars. Use as the orchestration layer for multi-channel product launches. Use when planning or executing a multi-channel product launch, or producing landing page, email, social, or ad copy.

affaan-m/everything-claude-code

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/everything-claude-code-conventions

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/frontend-design

Create distinctive, production-grade frontend interfaces with high design quality. Use when the user asks to build web components, pages, or applications and the visual direction matters as much as the code quality.

affaan-m/gget

gget CLI and Python workflow for quick genomic database queries, sequence lookup, BLAST-style searches, enrichment checks, and reproducible bioinformatics evidence logs.

affaan-m/literature-review

Systematic literature-review workflow for academic, biomedical, technical, and scientific topics, including search planning, source screening, synthesis, citation checks, and evidence logging.

affaan-m/motion-ui

Production-ready UI motion system for React/Next.js. Use when implementing animations, transitions, or motion patterns.

affaan-m/project-guidelines-example

Example project-specific skill template based on a real production application.

affaan-m/pubmed-database

Direct PubMed and NCBI E-utilities search workflows for biomedical literature, MeSH queries, PMID lookup, citation retrieval, and API-backed literature monitoring.

affaan-m/scholar-evaluation

Structured scholarly-work evaluation for papers, proposals, literature reviews, methods sections, evidence quality, citation support, and research-writing feedback.

affaan-m/uspto-database

USPTO patent and trademark data workflow for official record lookup, PatentSearch queries, TSDR checks, assignment data, and reproducible IP research logs.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

相关技能