global actorへの隔離
global actor は、アプリ全体で共有される一つのactorです。前のページのactorの例のように、actorはインスタンスごとに独立したisolation domainを持つのに対してglobal actorはアプリケーション全体で一つのisolation domainを持ちます。
では、global actorで状態、関数を隔離する例を、最も有名なglobal actorであるMainActorを例に解説します。
MainActorは最初からシステムが用意しているglobal actorであり、全ての処理がメインスレッド上で実行されるという特徴があります。
global actor への隔離は、クラス、関数、変数の宣言にアノテーションを書いて行います。MainActor なら @MainActor です。
@MainActorclass GameLibraryViewController: UIViewController { func updateUI() { // 画面に出ている表示を更新する }}
@MainActorvar libraryTitle = "ゲーム"
@MainActorfunc reloadLibrary() { libraryTitle = "更新したゲーム"}クラスに@MainActorをつけると、そのクラスのプロパティ、メソッドもMainActorのisolation domainに隔離されます。
関数や、変数には、それぞれの宣言に直前に、クラスと同様に@MainActorをつけることでisolation domainに隔離されます。libraryTitle と reloadLibrary() はクラスの外にありますが、GameLibraryViewController と同じisolation domainに隔離されます。
自分で作る global actor
Section titled “自分で作る global actor”MainActorは最初から用意されているglobal actorですが、自身でglobal actorを定義することもできます。
以下の例の通り、@globalActorアノテーションをつけることで、アプリ全体で共有されるglobal actorを定義することができます。
struct Videogame { var title: String}
@globalActorstruct MediaActor { actor ActorType { } static let shared = ActorType()}
@MediaActorvar videogames: [Videogame] = []
@MediaActorfunc addGame(_ game: Videogame) { videogames.append(game)}videogames と addGame は、どちらも MediaActor.shared に隔離されます。
そして、MediaActor の外から addGame を呼ぶ時には、await が必要です。
func register(_ game: Videogame) async { await addGame(game)}