Swift Academy · レッスン

Actorの分離とnonisolated

分離の境界について考えます。

レッスン 3/413 ステップ

「Actorの分離とnonisolated」はCoddyKit上の無料Swift Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSwift Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Swift Academyコースには全4レッスンが含まれています。

アクター分離とは

アクター分離とは、アクターの可変状態に触れられるのは、そのアクター上で実行されているコードだけであるという意味です。

ランタイムがアクセスを直列化するため、2つのタスクが状態を同時に変更することはなく、データ競合がなくなります。

actor Counter {
    private var value = 0
    func increment() { value += 1 }
}

アクターの呼び出し

アクターの外部から分離されたメンバーにアクセスすると、呼び出しは非同期になります。アクターが空くまで呼び出しが中断する可能性があるため、awaitが必要です。

let counter = Counter()
func useCounter() async {
    await counter.increment()
}

アクター内部:同期実行

アクター自身のメソッド内ではすでに分離された状態にあるため、状態には同期的にアクセスできます。selfに対してはawaitは必要ありません。

actor Counter {
    private var value = 0
    func incrementTwice() {
        value += 1 // synchronous: already isolated
        value += 1
    }
}

nonisolatedメンバー

可変状態に触れないメンバーにはnonisolatedを付けます。このようなメンバーはどこからでも同期的に実行でき、awaitも必要ありません。

不変データだけから作られる計算プロパティに適しています。

actor User {
    let id: Int
    var sessionCount = 0
    init(id: Int) { self.id = id }
    nonisolated var label: String { "User #\(id)" }
}

nonisolatedが安全な理由

nonisolatedメンバーが読み取れるのは、不変(let)の状態、またはそれ以外のSendableな状態だけです。

nonisolatedコンテキストから可変な分離状態にアクセスしようとすると、コンパイラーが拒否します。

actor User {
    let id: Int
    var sessionCount = 0
    init(id: Int) { self.id = id }
    // Error: cannot read mutable sessionCount here
    // nonisolated var bad: Int { sessionCount }
}

nonisolatedとプロトコル

アクターが同期的なプロトコルに適合するとき、nonisolatedは不可欠です。プロトコルのメソッドはasyncにできないため、分離された状態を使わないようにする必要があります。

actor Item: CustomStringConvertible {
    let name: String
    init(name: String) { self.name = name }
    nonisolated var description: String { "Item: \(name)" }
}

MainActor

@MainActorはコードをメインスレッドに分離するグローバルアクターです。UIの更新はここで行います。

型、メソッド、またはプロパティに注釈を付けて、メインアクター上で実行されるようにします。

@MainActor
final class ViewModel {
    var title = "Hello"
    func refresh() { title = "Updated" }
}

アクター間の切り替え

あるアクターから別のアクターを呼び出すと、ランタイムはエグゼキューターを切り替え、処理を中断します。その中断がまさにawaitが現れる場所です。

actor Database { func load() -> Int { 42 } }
@MainActor
func show(_ db: Database) async {
    let v = await db.load() // hop to db actor
    print(v)               // hop back to main
}

アクターの再入可能性

アクターは再入可能です。メソッドがawaitすると、awaitから再開する前に、アクターがキューに入っている別の処理を実行することがあります。

awaitの前に読み取った状態は、awaitの後では変わっている可能性があります。中断ポイントの後で前提を再確認してください。

actor Store {
    var ready = false
    func prepare() async {
        ready = false
        await Task.yield() // other calls may run here
        ready = true
    }
}

isolatedパラメーター

関数はisolatedなアクターパラメーターを受け取り、そのアクターのメンバーでなくても、関数本体をそのアクター上で実行できます。

func bump(on counter: isolated Counter) {
    // runs isolated to counter; synchronous access
}

サブシステム用のグローバルアクター

独自のグローバルアクターを定義して、サブシステム全体(たとえばレンダリングパイプライン)を1つのエグゼキューター上に分離できます。

@globalActor
actor RenderActor {
    static let shared = RenderActor()
}
@RenderActor func draw() { }

理解度チェック:分離

アクター分離についての理解度を確認しましょう。

まとめ:アクター分離とnonisolated

アクター分離は可変状態へのアクセスを直列化します。アクターをまたぐ呼び出しは非同期で、awaitが必要です。nonisolatedメンバーは分離から外れますが、不変またはSendableな状態だけを読み取ることができ、同期的なプロトコル適合に不可欠です。

@MainActorはコードをメインスレッドに固定し、アクターは再入可能であるためawaitの前後で状態が変わる可能性があります。また、グローバルアクターはサブシステム全体を分離します。これらのルールを理解することが、安全な並行処理の中心です。

無料で開始

AI チューターと学ぶ Swift — 無料

ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。

コース
122
レッスン
409

よくある質問

「Actorの分離とnonisolated」レッスンは無料ですか?

はい。「Actorの分離とnonisolated」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Swift Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Swift Academyコースには全4レッスンが含まれています。

「Actorの分離とnonisolated」で何を学びますか?

分離の境界について考えます。 ブラウザで直接実行するハンズオンコードでSwift Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Swift Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのSwift Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「Actorの分離とnonisolated」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このSwift Academyレッスンでコードを書いて実行できますか?

はい。すべてのSwift Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. データ競合の問題
  2. Sendableプロトコル
  3. Actorの分離とnonisolated
  4. 厳密な並行性チェックへの移行
← Swift Academyに戻る