Communitygithub.com

swift-concurrency-6-2

Swift 6.2 平易并发 — 默认单线程,使用 @concurrent 显式后台卸载,为主 Actor 类型提供隔离一致性。在采用 Swift 6.2 并发模型时使用 — 通过 @concurrent 卸载或解决主 Actor 隔离问题。

swift-concurrency-6-2 是什么?

该技能为采用 Swift 6.2 的“平易并发”模型提供全面的指导方案。在 Swift 6.2 中,代码默认以单线程方式运行,并发操作需要显式引入。这从根本上消除了常见的数据竞争错误,同时不影响性能。它涵盖了在 Swift 6.2 中迁移和设计并发代码的核心模式,包括:隔离一致性(isolated conformances),允许 MainActor 类型安全实现协议;全局/静态变量的保护;以及使用 @concurrent 进行显式后台工作卸载。该技能还详细介绍了 MainActor 默认推断模式,该模式可以减少大量 @MainActor 注解。它支持在 Xcode 26 中通过构建设置逐步启用这些特性,并提供从 Swift 5.x/6.0/6.1 项目的具体迁移步骤。适用范围包括 Apple 平台、SPM 包和服务器端 Swift 项目。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/ECC/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 及更早版本中,异步函数可能会被隐式卸载到后台线程,即使在看似安全的代码中也会导致数据竞争错误:

// 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 修复了此问题:默认情况下,异步函数会停留在调用方的 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()  // 正确
}

MainActor 默认推断模式

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(NonisolatedNonsendingByDefault)。启用这些设置后,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 编译器 > 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 应用)
  • 性能优化 — 将特定的重计算卸载到后台

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/content-engine

Create platform-native content systems for X, LinkedIn, TikTok, YouTube, newsletters, and repurposed multi-platform campaigns. Use when the user wants social posts, threads, scripts, content calendars, or one source asset adapted cleanly across platforms.

affaan-m/ECC

Multi-platform content distribution across X, LinkedIn, Threads, and Bluesky. Adapts content per platform using content-engine patterns. Never posts identical content cross-platform. Use when the user wants to distribute content across social platforms.

affaan-m/fal-ai-media

Unified media generation via fal.ai MCP — image, video, and audio. Covers text-to-image (Nano Banana), text/image-to-video (Seedance, Kling, Veo 3), text-to-speech (CSM-1B), and video-to-audio (ThinkSound). Use when the user wants to generate images, videos, or audio with AI.

affaan-m/manim-video

日本語翻訳:このファイルは manim-video 用の日本語翻訳が必要です

affaan-m/remotion-video-creation

Remotion のベストプラクティス - React で動画を作成する。3D、アニメーション、音声、字幕、チャート、トランジションなどをカバーするドメイン固有の29のルール。

affaan-m/video-editing

AI-assisted video editing workflows for cutting, structuring, and augmenting real footage. Covers the full pipeline from raw capture through FFmpeg, Remotion, ElevenLabs, fal.ai, and final polish in Descript or CapCut. Use when the user wants to edit video, cut footage, create vlogs, or build video content.

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.

agent-self-evaluation

Use after completing any non-trivial task. The agent self-rates its output on 5 axes — accuracy, completeness, clarity, actionability, conciseness — with concrete evidence per criterion. Produces a structured 1-5 scorecard with specific improvement suggestions.

agent-sort

Build an evidence-backed ECC install plan for a specific repo by sorting skills, commands, rules, hooks, and extras into DAILY vs LIBRARY buckets using parallel repo-aware review passes. Use when ECC should be trimmed to what a project actually needs instead of loading the full bundle.

ai-first-engineering

Engineering operating model for teams where AI agents generate a large share of implementation output. Use when setting team process, review gates, or ownership rules for a codebase largely written by agents.

ai-regression-testing

Regression testing strategies for AI-assisted development. Sandbox-mode API testing without database dependencies, automated bug-check workflows, and patterns to catch AI blind spots where the same model writes and reviews code. Use when adding regression coverage to AI-assisted code, or when the same model both wrote and reviewed a change.

android-clean-architecture

Clean Architecture patterns for Android and Kotlin Multiplatform projects — module structure, dependency rules, UseCases, Repositories, and data layer patterns. Use when structuring modules, layers, or data flow in an Android or KMP project.

angular-developer

Generates Angular code and provides architectural guidance. Trigger when creating projects, components, or services, or for best practices on reactivity (signals, linkedSignal, resource), forms, dependency injection, routing, SSR, accessibility (ARIA), animations, styling (component styles, Tailwind CSS), testing, or CLI tooling.

相关技能