Swiftの開発者で、以前はCrashlyticsとAppleにいたMatt Massicotte氏が、Swiftの並行処理を使いやすくし、再発する問題を解決するために、陥りやすい罠を意識しながら、多くの便利なレシピを集めたGitHubのリポジトリを最近立ち上げた。
Swiftの並行プログラミングの物語は、Swift 5.5でのasync/await
とアクターのサポートから、Swift 5.10での完全なデータ分離と構造化された並行処理の導入まで、その開始以来、持続的なペースで進化している。すべての新しい並行処理指向の機能を使いこなすことは、それ自体が非常に大変な作業であるが、さらに物事を難しくするために、Swiftの並行処理プリミティブは、Grand Central Dispatch(GCD)のような以前の技術やライブラリと共存する必要がある。
この文脈において、Massicotte氏のプロジェクトは、Swiftの並行処理を採用し、GCDから移行する際に直面する可能性のある解決策と危険性の両方を文書化し、共有することを目的としている。
Swiftの並行処理は本当に使いにくいです。私は、あなたが途中で直面するかもしれない解決策と危険性を文書化し、共有することは便利だと思いました。私は、これが包括的であるとか、提示された解決策が素晴らしいと言っているわけではありません。私も勉強中なのです。特に問題点についての投稿は大歓迎です!
このリポジトリはいくつかのセクションで構成されており、それぞれが非同期コンテキストの作成という非常に基本的なタスクから、プロトコル内での並行性の扱い方、分離、SwiftUIなど、1つの主要なトピックに専念している。
例えば、Massicotte氏は、SwiftUIの同時実行に関する1つの厄介な詳細は、SwiftUIのView
のbody
アクセッサのみがMainActor
-safeであり、View
で宣言された他の関数やプロパティが分離されず、競合状態のリスクにさらされることであると説明している。彼が提案する解決策は、より複雑なビューのために@MainActor
属性を明示的に宣言することだ。
@MainActorstruct MyView:View var body: some View { Text("Body") }}
Massicotte氏は、MainActor
-isolated型を、自分が定義していないプロトコルに準拠させたい場合について説明している。
ご存知のように、アクターは、async
メソッドだけが外部からそのステートにアクセスできる必要がある。その場合、コンパイラは競合状態が発生しないことを保証できる。したがって、アクターから分離された型、例えばMainActor
の内部でしか使用できない型が、非同期メソッドを含むプロトコルに準拠しなければならない場合は、少し注意が必要だ。もっとも簡単な解決策は、"non-isolated"適合に頼ることで、nonisolated
キーワードを使ってコンパイラに指示すること、または代わりに委任を選択して、問題を完全に回避できる。
前述したように、Massicotte氏が説明する問題点は数多くあり、その解決策もここでは紹介しきれないほどたくさんある。提案された解決策が完全に満足のいくものでなくても、このリポジトリはSwiftの並行処理を使用するときにうまくいかない可能性があることを認識するのに役立ち、非常に便利なリソースとなるだろう。