以下の記事を参考にDispatchqueueの種類ごとにPlaygroundで実行してみた
実行環境:
Xcode13.0
Swift5.2
メインキュー
sync(同期)
// メインキューは直列(前のタスクが完了次第、次のタスクが実行される) let mainQueue = DispatchQueue.main // syncを使うと呼び出し元がブロックされる print("start") for i in 0...5 { mainQueue.sync() { print(i) } } print("end")
実行結果
error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0). The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation.
async(非同期)
// 非同期なので呼び出し元がブロックされずstart、endが最初に出力される // 直列なので番号は順番に出力される print("start") for i in 0...5 { mainQueue.async() { sleep(1) print(i) } } print("end")
実行結果
start end 0 1 2 3 4 5
グローバルキュー
sync(同期)
// グローバルキューは並列(前のタスクの処理状況に関わらず、次のタスクが実行される) let grobalQueue = DispatchQueue.global(qos: .default) // 同期なので呼び出し元がブロックされてendが最後に出力される // 並列だが同期なので番号は順番に出力される print("start") for i in 0...5 { grobalQueue.sync() { sleep(1) print(i) } } print("end")
実行結果
start 0 1 2 3 4 5 end
async(非同期)
// 非同期なので呼び出し元がブロックされずstart、endが最初に出力される // 並列なので番号が出力される順番はバラバラ print("start") for i in 0...5 { grobalQueue.async() { sleep(1) print(i) } } print("end")
実行結果
start end 4 2 3 0 1 5
自分でDispatchQueueを用意する場合
// 直列 let serialQueue = DispatchQueue(label: "serialQueue") // 並列 let parallelQueue = DispatchQueue(label: "parallelQueue", attributes: .concurrent)
同期および非同期での実行結果はメインキュー、グローバルキューの結果から推察できる通り。
メインキューではエラーになったが直列で同期の場合は以下のようになる。
print("start") for i in 0...5 { serialQueue.sync() { sleep(1) print(i) } } print("end")
実行結果
start 0 1 2 3 4 5 end