Swift3になってから、どうやってDispatchQueueの asyncAfter をキャンセルしようか考えていたのですが、
DispatchWorkItem
を使えば簡単にできそうな気がしたので DispatchQueue の extension として書いてみました
extension DispatchQueue {
func cancelableAsyncAfter(deadline: DispatchTime, execute: @escaping () -> Void) -> DispatchWorkItem {
let item = DispatchWorkItem(block: execute)
asyncAfter(deadline: deadline, execute: item)
return item
}
}
使い方としてはこんな感じです↓
let item = DispatchQueue.main.cancerableAsyncAfter(deadline: .now() + 3.0) {
print("execute!")
}
item.cancel()
実行前 であれば、DispatchWorkItem
のインスタンスに対して cancel() を呼んであげると、実行させずに済みます。
ちなみに、 cancel() を呼び出すまでは、実際に asyncAfter で呼び出されても、呼び出す前でも、手動で perform() を呼び出せば
実行することができます。
let item = DispatchQueue.main.cancerableAsyncAfter(deadline: .now() + 3.0) {
print("execute!")
}
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
item.performe() // 実行される
item.cancel()
item.performe() // 実行されなくなる (item.isCancelledがtrueになる)
}
// ========== (実行結果)
"execute!"
"execute!"
ひとまずはこれで良さそう。