Swift Concurrency 6 2

作者 affaan-mef648e01899b無授權條款275K 個星標收錄於 2026年10月8日更新於 2026年10月8日儲存庫3 天前更新

Swift 6.2のアクセシブルな並行処理——デフォルトはシングルスレッド、@concurrentは明示的なバックグラウンドオフロードに使用し、分離の一貫性はMainActor型に使用する。

AI 產生的概覽

說明 Swift 6.2 並行模式:預設單執行緒、以 @concurrent 明確卸載至背景,以及 MainActor 隔離。

功能
說明 Swift 6.2 的並行模型:非同步函式預設留在呼叫端的 actor 上,背景執行須以 @concurrent 明確啟用。內容涵蓋隔離一致性、以 MainActor 保護全域與靜態狀態、MainActor 預設推論、移轉步驟、最佳實務與反面模式。產出的是指引與程式碼範例,而非可執行的成品。
適用情境
適用於將 Swift 5.x 或 6.0/6.1 專案移轉至 Swift 6.2、解決資料競爭安全的編譯器錯誤、設計以 MainActor 為核心的 App 架構,或將 CPU 密集工作卸載至背景執行緒時。
執行需求
不隨附指令碼或工具,僅為說明性內容。套用其中範例需要 Swift 6.2 工具鏈、Xcode 26 或 Swift Package Manager 中啟用可存取並行建置選項的設定,並開啟 SE-0466 與 SE-0461 功能。

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
// Swift 6.1: ERROR@MainActorfinal 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
// Swift 6.2: OK — async stays on MainActor, no data race@MainActorfinal 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型が非分離プロトコルに安全に準拠できるようになった:

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

コンパイラはこの一貫性がMainActor上でのみ使用されることを保証する:

swift
// OK — ImageExporter is also @MainActor@MainActorstruct ImageExporter {    var items: [any Exportable]
    mutating func add(_ item: StickerModel) {        items.append(item)  // Safe: same actor isolation    }}
// ERROR — nonisolated context can't use MainActor conformancenonisolated 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
// Swift 6.1: ERROR — non-Sendable type may have shared mutable statefinal class StickerLibrary {    static let shared: StickerLibrary = .init()  // Error}
// Fix: Annotate with @MainActor@MainActorfinal class StickerLibrary {    static let shared: StickerLibrary = .init()  // OK}

MainActorデフォルト推論パターン

Swift 6.2ではMainActorをデフォルトで推論するパターンが導入された——手動の注釈なし:

swift
// 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に留まり、可変状態へのアクセスが安全になる。これらの設定なしでは、このコードにはデータ競合がある——コンパイラがフラグを立てる。

swift
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 awaitlet 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 ラッパーではなく分離の一貫性を使用する
  • 段階的に移行する —— ビルド設定で一度に1つの機能を有効化する

避けるべきアンチパターン

  • すべての非同期関数に @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アプリ)
  • パフォーマンス最適化——特定の重い計算をバックグラウンドにオフロードする場合

來源與署名

來源:affaan-m/ecc位於docs/ja-JP/skills/swift-concurrency-6-2提交ef648e0

授權條款: 無授權條款

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架