【GCD】Swiftにおける並列プログラミングの基本


この記事は何か?

GCDを利用した並列プログラミングについて調べました。

環境

macOS 10.15.7
Xcode 12.1
Swift 5.3

用語

スレッド

すべての iOS アプリケーションにはメインスレッドがあります。メインスレッドはUIを表示したり、発生するイベントに備えて待機します。
メインスレッドで複雑な計算をすると、処理が遅くなってアプリがフリーズするかもしれません。そのような場合に役立つのがマルチスレッドです。負荷が高いタスクをバックグラウンドスレッドに移し、タスクが完了するとメインスレッドに戻ってくる仕組みです。

キュー

並列または直列になって、スレッドで実行されるのを待機している一連のコードブロックです。
Swiftではキューを管理するだけでよく、スレッドを意識する必要は全くありません。キューのコードを実行するために必要なスレッドの提供および割り当ては、システムが行います。

Grand Central Dispatch: GCD

キューの管理を担当するAPIです。

GCDの役割

  • キューを作成する
  • コードブロックをキューに預ける

メインキュー

全ての中で最も重要なキュー。UIに影響を与えるコードブロックはすべて、メインキューで実行されなければならない。

バックグラウンドキュー

長く存続するUIタスク以外のタスクをキューに入れるために使用します。
多くの場合、メインのUIキューと同時に並行して実行されます。

バックグラウンドキューの優先度レベル

ユーザー・インタラクティブ

.userInteractive
ユーザー・インタラクティブ・タスクは、システム上で最も優先度の高いタスクです。このレベルは、ユーザーと対話したり、アプリのユーザーインターフェイスをアクティブに更新したりするタスクやキューに使用します。たとえば、アニメーションだったり、イベントをインタラクティブに追跡したりするクラスに使用します。

ユーザー・イニシアティブ

.userInitiated
ユーザー・イニシアティブ・タスクは、システム上での優先順位では、ユーザー・インタラクティブ・タスクに次ぐものです。ユーザーが何かをしている間にすぐに結果が得られるタスクや、ユーザーがアプリを使用できなくなるようなタスクには、このクラスを割り当てます。たとえば、このQuality-of-Serviceレベルを使用して、ユーザーに表示する電子メールのコンテンツをロードすることができます。

ユーティリティ

.utility
ユーティリティタスクの優先度は、ユーザーが起動したタスクやユーザーが対話するレベルよりは低いですが、バックグラウンドタスクよりは高い優先度です。このサービス品質クラスは、ユーザーがアプリを使い続けることを妨げないタスクに割り当てます。たとえば、ユーザーが積極的に進行状況をフォローしない長期的なタスクにこのクラスを割り当てることができます。

バックグラウンド

.background
バックグラウンド タスクは、すべてのタスクの中で最も優先度が低いものです。このレベルを、アプリがバックグラウンドで実行されている間に作業を実行するために使用するタスクまたはディスパッチ キューに割り当てます。例えば、メンテナンス タスクまたはクリーンアップです。

標準

.default
優先度は、ユーザー始動タスクとユーティリティの間になるレベル。

コードをキューに追加する

同期的に追加する

タスク項目がsyncメソッドによって同期的に実行される場合、プログラムは実行が終了するまで待機してからメソッドが呼び出されます。

DispatchQueue.main.sync {
    // Code to be executed
}

このコードは「メインスレッドに同期的なキューをディスパッチする」と理解できます。

非同期的に追加する

タスク項目がasyncメソッドによって非同期的に実行されると、メソッドがすぐに呼び出されます。

DispatchQueue.global().async {
    // Code to be executed
}

このコードは「バックグラウンドスレッドに非同期的なキューをディスパッチする」と理解できます。