概要
最近仕事で非同期を同期にして処理するニーズがあったので、古いコードでライブラリも使えないので、GCD使って簡単に実装してみました。
let task = Task()
task.doSomeThingAsync()
task.waitUntilCompleted()
print("finished")
詳細
- DispatchSemaphore インスタンス生成
- semaphoreインスタンスqueue止めたいところwait呼ぶ
- 非同期処理終わったらsemaphoreインスタンス signal呼ぶ
コード
class Task {
var semaphore: DispatchSemaphore?
func doSomeThingAsync() {
semaphore = DispatchSemaphore(value: 0)
DispatchQueue.global().async { [weak self] in
print("doing task...")
sleep(1)
print("task done!")
// 実行終了
self?.semaphore?.signal()
self?.semaphore = nil
}
}
func waitUntilCompleted(_ timeout: TimeInterval = 0) {
// 0の場合はtimeout設定しない
if timeout == 0 {
semaphore?.wait()
return
}
semaphore?.wait(timeout: .now() + .milliseconds(Int(timeout * 1000)))
}
}
注意:
waitだとsignal呼ばないとqueueをブロックしてしまうので、実行queueはmain queueではなく別のqueueにするか、func wait(timeout: DispatchTime)
使ったほうが無難.