concurrency-expert について
concurrency-expertは、Swift 6.2以降のコードベースにおける並行処理の問題をレビューし、修正するスキルです。Actor分離やSendableの安全性、最新の並行処理パターンを用い、既存の動作を保つことを目指します。
主な機能
- 01コンパイラ診断とActorコンテキストの分析
- 02UI関連コードへのActor分離の適用
- 03共有状態とグローバル状態の保護
- 04メインActor外への処理移動
- 05Swift並行処理の移行支援
活用シーン
- 01厳密な並行処理チェックのエラー解消
- 02UI関連型の安全な分離
- 03バックグラウンド処理のメインActor外への移動
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ patrickserrano/ skills --skill concurrency-expertインストール後、Claude Code で/concurrency-expertを入力して読み込まれたか確認します。
詳細
Swift Concurrency のエキスパート
概要
Swift 6.2 以降のコードベースで、アクター分離、Sendable の安全性、最新の並行処理パターンを適用し、動作への影響を最小限に抑えながら Swift Concurrency の問題を確認して修正します。
ワークフロー
1. 問題をトリアージする
- コンパイラ診断の正確な内容と、問題の原因となっているシンボルを記録します
- プロジェクトの並行処理設定を確認します。Swift 言語バージョン(6.2 以降)と strict concurrency レベルを確認します
- approachable concurrency(デフォルトのアクター分離/デフォルトでの MainActor 分離)が有効かどうかを確認します
- 現在のアクターコンテキスト(
@MainActor、actor、nonisolated)を特定します - コードが UI に関連するものか、メインアクター以外で実行することを意図したものかを確認します
2. 最小限の安全な修正を適用する
データ競合の安全性を満たしながら、既存の動作を維持する修正を優先します。
よくある修正:
| 問題 | 修正 |
|---|---|
| UI に関連する型 | 型またはメンバーに @MainActor を付けます |
| メインアクター上の型でのプロトコル適合 | 適合を分離します:extension Foo: @MainActor SomeProtocol |
| グローバル/静的状態 | @MainActor で保護するか、アクター内に移します |
| バックグラウンド処理 | nonisolated 型の非同期関数に @concurrent を使用します |
| Sendable に関するエラー | 不変型/値型を優先し、適切な場合にのみ Sendable を追加します |
Swift 6.2 の主な変更点
デフォルトのアクター分離
Swift 6.2 では、並行処理を導入するまではデフォルトでシングルスレッドのままです。
// In Swift 6.2 with approachable concurrency enabled,
// this no longer produces a data race 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
}
// Safe - runs on main actor by default
return await photoProcessor.extractSticker(data: data, with: item.itemIdentifier)
}
}
分離された適合
メインアクターの状態を必要とする適合がサポートされるようになりました。
protocol Exportable {
func export()
}
// Isolated conformance - safe because compiler ensures
// it's only used on the main actor
extension StickerModel: @MainActor Exportable {
func export() {
photoProcessor.exportAsPNG()
}
}
グローバル状態の保護
// Protect with @MainActor
@MainActor
final class StickerLibrary {
static let shared: StickerLibrary = .init()
}
// Or enable main-actor-by-default mode for the whole project
バックグラウンドへの処理のオフロード
@concurrent を使用すると、コードを並行処理用スレッドプールで明示的に実行できます。
nonisolated struct PhotoProcessor {
@concurrent
func process(data: Data) async -> ProcessedPhoto? {
// Runs on background thread
}
}
// Caller adds await
processedPhotos[item.id] = await PhotoProcessor().process(data: data)
移行チェックリスト
- ビルド設定で Swift のバージョンを確認します(6.2 以降が必要です)
- ビルド設定で approachable concurrency 機能を有効にします
- Swift 移行ツールを実行します:
swift.org/migration - 上記のパターンを使って、残りのコンパイラエラーを修正します
- 十分にテストします。並行処理のバグが実行時に表面化する場合があります
よくあるパターン
UI に関連するクラス
@MainActor
final class ViewModel {
var items: [Item] = []
func load() async {
items = try await service.fetchItems()
}
}
バックグラウンド処理
nonisolated struct ImageProcessor {
@concurrent
static func resize(_ image: UIImage, to size: CGSize) async -> UIImage {
// Heavy work runs off main actor
}
}
共有可変状態のためのアクター
actor Cache {
private var storage: [String: Data] = [:]
func get(_ key: String) -> Data? {
storage[key]
}
func set(_ key: String, value: Data) {
storage[key] = value
}
}
ビルド設定
Xcode の「Swift Compiler - Concurrency」で次の設定を有効にします:
SWIFT_STRICT_CONCURRENCY= complete- approachable concurrency 機能(Swift 6.2 以降)
または、Package.swift で設定します:
swiftSettings: [
.enableExperimentalFeature("StrictConcurrency")
]
コメント
Markdown 対応