Swiftで非同期処理を行うとした際、いくつかの手法があり、どれを使うのが良いか判断に迷うことが多いため、自分なりに特徴を調べてみました。
※結論だけ先に述べると、特別な理由がない限りは「Swift Concurrency」一択になります。
GCD
- 非同期処理の管理
ディスパッチキューを用いて非同期処理をキュー管理できます。 - 性能と効率
高性能で低オーバーヘッドのため、上手に使えば高性能ですが、とても繊細に扱わないとスレッド爆発等の問題を引き起こしやすい構造になっています。 - 非同期処理の制御
非同期処理の制御にはクロージャ(ブロック)を使います。
この関係で直感的なコーディングが難しいことがあります。
スレッド爆発とは、大量のスレッドが生成されリソースの消費が著しく増加することを指します。これにより、パフォーマンスの低下やメモリ不足、さらにはアプリケーションのクラッシュを引き起こす可能性があります。
Operation
- 非同期処理の管理
Operation
やOperationQueue
を使用して処理をキュー管理できます。
GCDと異なる点としては、キューの最大同時実行数を設定できる点が挙げられます。
またタスク間の依存関係の管理やキャンセル機能も有しているため、GCDより高機能になります。 - 性能と効率
GCDの上位レイヤーとなるため、GCDと比べると若干オーバーヘッドがあります。
とはいえ、一般的なアプリ開発では気にするほどではないでしょう。 - 非同期処理の制御
表現が正しくないかもしれませんが、非同期処理の制御にはクロージャ(ブロック)を使います。
この関係で直感的なコーディングが難しいことがあります。
Swift Concurrency
- 非同期処理の管理
Taskを使って処理を管理します。
同期処理のようにコードを記載できるため、管理するといった感覚を持たなくても良いように工夫されています。 - 性能と効率
Swiftのコンパイラは、効率的に最適化するため、Operationとほぼ同等であると考えられます。 - 非同期処理の制御
async / await構文にて同期処理のようにコードを書けるようになっています。
このためコールバック地獄(callback hell)を避けられ、コードが簡潔で読みやすくなります。
また非同期処理ではデータ競合に注意しなければいけませんが、Strict Concurrency CheckingというXcodeの機能で、競合を起こす可能性のあるコードはコンパイルエラーにしてくれる機能があり安全です。
結論
iOS13未満をサポートする必要がないアプリであれば、特別な理由がない限り「Swift Concurrency」一択になるかと思います。
同期的に処理をかけたり、Actor / Strict Concurrency Checkingといった安全にコーディングできる仕組みがあるといった部分が大きいと感じました。
方式 | 特徴 |
GCD | 高性能で低オーバーヘッドではあるが、メリットを活かすには繊細な制御が必要。 |
Operation | GCDと比較し、キュー管理機能が充実。 コールバック実装が必要なため、GCD同様コールバック地獄に陥りやすい。 |
Swift Concurrency(Async / Await) | Swift 5.5から登場。iOS13以上で利用可。 同期的に処理を書けるので直感的。 Actor等を利用することでデータ競合が起きにくい。 |
コメント