非同期処理まとめ(swift)


非同期処理とは

ある処理を実行中に別の処理を止めないこと処理を非同期処理という。
swiftではスレッドを利用して非同期処理を実現する。

スレッド:CPUにおける最小の実行単位。
     スレッド数はCPUが担当できる仕事の数。

どんな場面で非同期処理が必要?

アニメーションやサーバーとの通信など、時間がかかる処理・重い処理などに使用します。

マルチスレッド処理

通常プログラムはメインスレッドという単一のスレッドから処理を開始するが、別のスレッドを作成して別の処理を実行させることができる。

!!ただし、iosにおいてユーザインターフェイスに関わる処理は通常メインスレッドで行われる!!

しかし!!マルチスレッドは正しく実行しなければ下記の深刻な問題が発生するので注意。
①メモリの枯渇
②複数スレッドから同一データを更新するなどの不整合・衝突が発生
③デッドロック

非同期処理を行う3つの方法

①GCD
②Operation,OperationQueueクラスを用いる方法
③Threadクラスを用いる方法

今回は一番簡単なGCDを次の項目でまとめます。

GCD(Grand Central Dispatch)

GCDは非同期処理を容易にするためのC言語ベースのシステムレベルでの技術。
GCDではキューを通して非同期処理を行うので、直接スレッドを管理することはない。
プログラマが行うのはタスクをキューに追加することだけ。

ディスパッチキューについて

GCDのキューはディスパッチキューと呼ぶ。次の2つに大別される。

①直列ディスパッチキュー
現在実行中の処理を待ってから、次の処理を実行する。

②並列ディスパッチキュー
現在実行中の処理の終了を待たずに、次の処理を並列して実行する。

ディスパッチキューを利用するには、既存のディスパッチキューを取得するか、新規のディスパッチキューを生成する必要がる。

ディスパッチキューの取得

GCDは既存のディスパッチキューとして一つのメインキューと複数のグローバルキューを提供する。

①メインキュー:メインスレッドでタスクを実行する直列ディスパッチキュー

sample
    let queue = DispatchQueue.main

②グローバルキュー:実行優先度を指定して取得する並列ディスパッチキュー

sample
    let queue = DispatchQueue.global(qos :.userIntiated)

QoS(Quality of Service):優先度

種類 名称
userInteractive ユーザーからの入力を元に即座に反映させる必要がある動作用。アニメーションの実行など。
userIntiated ユーザーからの入力を反映させる一般動作用。
default デフォルト。明示的に使用すべきではない。
utility 視覚的な情報を伴いながらも緊急度が低い動作用。プログレスパーなど。
background 数分かかっても問題ない処理などに用いる。

新規のディスパッチキューを生成

並列処理タイプ

sample
    let queue = DispatchQueue(label :"キュー",qos :.userIntiated, attributes :.concurrent )

タスクの追加

タスクの呼び出しもとがタスクの処理完了を待つかどうかで、2種類の追加方法がある。
①同期的追加:タスクをディスパッチキューに追加した後、そのタスク完了まで移行しない

つまり通常と同じ!

sample
    dispatchQueue.sync{
        print("同期的追加")
    }

②非同期的追加:タスクをディスパッチキューに追加したら、その処理を待たずに次の行へ移行する。

sample
    dispatchQueue.async{
        print("非同期的追加")
    }

タスクの遅延実行

設定時間後にタスクが追加される。
呼び出し元で遅延は発生しない。

sample
    dispatchQueue.asyncAfter(deadline :.now() + 5){
        print("5秒後に処理を実行")
    }

ディスパッチキューの一時停止と再開

sample
    //一時停止
    dispatchQueue.suspend()

    //再開
    dispatchQueue.resume()