##背景
非同期で幾つか処理をしている状態で、値の取得が完了したら後続処理を行いたい場合がありました。
セマフォで後続処理を行わないようにしていましたが、記述箇所が増えてしまい、
見通しが悪くなってきたので、待機条件と後続処理をBlockで記述できるようにExtensionを書きました。
##コード
/// 条件をクリアするまで待ちます
///
/// - Parameters:
/// - waitContinuation: 待機条件
/// - compleation: 通過後の処理
func wait(_ waitContinuation: @escaping (()->Bool), compleation: @escaping (()->Void)) {
var wait = waitContinuation()
// 0.01秒周期で待機条件をクリアするまで待ちます。
let semaphore = DispatchSemaphore(value: 0)
DispatchQueue.global().async {
while wait {
DispatchQueue.main.async {
wait = waitContinuation()
semaphore.signal()
}
semaphore.wait()
Thread.sleep(forTimeInterval: 0.01)
}
// 待機条件をクリアしたので通過後の処理を行います。
DispatchQueue.main.async {
compleation()
}
}
}
##使い方
var imgData: NSData! = nil
DispatchQueue.global().async {
imgData = NSData(contentsOf: URL(string: "http://hogehoge.com/fugafuga.png")!)
}
// dataを取得するまで待ちます
wait( { return imgData == nil } ) {
// 取得しました
print("finish")
UIImage(data: imgData as Data)
}