Sendableプロトコル
並行性の境界を越えて安全な型であることを示します。
「Sendableプロトコル」はCoddyKit上の無料Swift Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSwift Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Swift Academyコースには全4レッスンが含まれています。
Sendableの意味
Sendableはマーカープロトコルです。これに準拠する型は、データ競合を引き起こすことなく並行実行の境界を越えて安全に共有できることを保証します。
メソッドはありません。スレッド安全性についてコンパイラーが検証する保証です。
protocol Sendable {}値型はSendableになることが多い
保存プロパティがすべてSendableである構造体と列挙型は、自動的に準拠できます。
値は渡されるとコピーされるため、各タスクはそれぞれ独立したコピーを取得します。
struct User: Sendable {
let id: Int
let name: String
}暗黙的な準拠
多くの値型はSendableに暗黙的に準拠します。対象となるのは、Sendableなメンバーを持つ非公開のfrozen構造体と列挙型、Sendableな型のタプル、メタ型です。
内部用の値型では、: Sendableをまったく記述しないこともよくあります。
enum Direction { case north, south, east, west }
// Implicitly Sendable: no associated non-Sendable data構造体がSendableではない場合
structが非Sendableの格納プロパティを保持している場合、そのstructはSendableではありません。
ここではクラス参照によって共有された可変状態に到達できるため、コンパイラーは自動適合を拒否します。
final class Box { var value = 0 }
struct Wrapper { // not Sendable
let box: Box // class with mutable state
}クラスとSendable
クラスは参照型であるため、コピーしても同じインスタンスを共有します。クラスがSendableになるのは、finalであり、すべての格納プロパティが不変かつSendableである場合だけです。
final class ImmutablePoint: Sendable {
let x: Double
let y: Double
init(x: Double, y: Double) { self.x = x; self.y = y }
}@unchecked Sendable
クラスがスレッドセーフ(ロックで状態を保護している)だと分かっていても、コンパイラーがそれを証明できない場合があります。そのときは@unchecked Sendableを使って、安全性を手動で保証します。
これは安全性チェックを回避する手段です。正しさについては自分で責任を負うことになります。
import Foundation
final class Cache: @unchecked Sendable {
private let lock = NSLock()
private var storage: [String: Int] = [:]
func set(_ k: String, _ v: Int) {
lock.lock(); defer { lock.unlock() }
storage[k] = v
}
}@Sendableクロージャ
クロージャにも@Sendableを付けられます。このようなクロージャは並行処理の境界を越えて渡せるため、コンパイラーはSendableな値だけをキャプチャしていることを検証します。
func run(_ work: @Sendable () -> Void) {
work()
}
let name = "Ada" // immutable, Sendable
run { print(name) }可変状態のキャプチャは拒否される
@Sendableクロージャは可変変数をキャプチャできません。2つのタスクがその変数を同時に変更する可能性があるためです。
次のコードのキャプチャはコンパイラーによってエラーになります。
var counter = 0
// Error: @Sendable closure captures mutable var
// run { counter += 1 }非同期APIでのSendable
並行処理のエントリーポイントではSendableが必要です。Taskクロージャは@Sendableであり、他のアクターに渡す値もSendableでなければなりません。
このように、型システムはスレッドセーフでないデータがタスク間に漏れ出すのを防ぎます。
func process(_ user: User) async {
Task {
// user is Sendable, safe to capture
print(user.name)
}
}ジェネリックでのSendable制約
ジェネリックでSendableを要求できます。引数を使ってタスクを生成する関数では、その引数にSendable制約を付けるべきです。
func dispatch<T: Sendable>(_ value: T) {
Task { print(value) }
}Sendableとアクター
Sendableは「この値を安全に渡せるか」を示し、actorは「可変状態をどのように保護するか」を示します。
両者は組み合わせて使えます。アクターの状態へのアクセスは直列化されるため、アクターは暗黙的にSendableです。
actor Logger { } // actors are implicitly Sendable理解度チェック:Sendable
Sendable適合についての理解度を確認しましょう。
まとめ:Sendableプロトコル
Sendableは、並行処理の境界を安全に越えられる型を示します。不変の値型は自動的に適合し、不変のfinalクラスも適合できます。スレッドセーフなクラスには@unchecked Sendableを使います。
@SendableクロージャはSendableな値だけをキャプチャでき、非同期APIでは安全でない共有を防ぐためにSendableが必要です。アクターと組み合わせることで、SendableはSwiftのデータ競合安全性を型レベルで支える基盤になります。
よくある質問
「Sendableプロトコル」レッスンは無料ですか?
はい。「Sendableプロトコル」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Swift Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Swift Academyコースには全4レッスンが含まれています。
「Sendableプロトコル」で何を学びますか?
並行性の境界を越えて安全な型であることを示します。 ブラウザで直接実行するハンズオンコードでSwift Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Swift Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのSwift Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「Sendableプロトコル」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このSwift Academyレッスンでコードを書いて実行できますか?
はい。すべてのSwift Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- データ競合の問題
- Sendableプロトコル
- Actorの分離とnonisolated
- 厳密な並行性チェックへの移行