LoginSignup
2
7

More than 1 year has passed since last update.

【Swift】複数の非同期処理(ループ処理)の完了後に次の処理に移る方法(DispatchGroup)

Last updated at Posted at 2020-08-28

1. やりたいこと

API通信で非同期処理を実装する際に、複数の通信(ループ処理)がある場合に、最後までループ処理が完了した後にその結果を取り出す。

2. 実装方法

 DispatchGroup()を使用した実装方法を示す。ここで、クロージャhogefugaは通信処理である。
 以下のスニペットで、DispatchGroup()がない状態を想定すると、「Sequence #4」は hogefuga のコールバック取得よりも先に実行される可能性が高いため、Sequence #1 → 4 → 5 → 2 → 3の順になる。
 DispatchGroup()を使用することで、Sequence #1 → 4 → 2 → 3 → 5の順になる。

 ポイントは、dispatchGroup.enter()dispatchGroup.leave()が2回あること。
 最初のenter()でカウンターが+1され、 hoge 処理が実行開始される。「Sequence #1」の通信が完了する頃には「Sequence #2」の通信を開始しているため、処理は「Sequence #2」の通信の結果を待たずに「Sequence #4」に移行するが、この時「Sequence #2」の位置のenter()によってカウンターが上がっているため、「Sequence #3」のコールバック完了まで「Sequence #5」に移行しない。

 なお、同様の機能を果たす実装方法は他にも考えられるが、検討した限りはこれが良いと思った。また、実際にはエラーに対する条件分岐などが入り込むが、この考え方を使用できる。

let dispatchGroup = DispatchGroup()
let dispatchqueue = DispatchQueue.global(qos: .userInitiated)

dispatchGroup.enter()
dispatchqueue.async {
   hoge { foos in
       // Sequence #1
       for foo in foos {
          dispatchGroup.enter()
               // Sequence #2
               fuga { bars in
                   dispatchGroup.leave()
                   // Sequence #3
               }                
       }
       // Sequence #4
       dispatchGroup.leave()
   }
}
dispatchGroup.notify(queue: dispatchqueue){
   // Sequence #5
}   

3. 参考リンク

Swiftで複数の非同期処理の完了時に処理を行う
DispatchQueueを使って容量のあるファイルをダウンロードする方法

2
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
7