GCD 是我們常用的多執行緒技術,基於C語言給我們帶來了高效的執行速度,通過block讓程式碼的呼叫更加緊湊。但是對GCD中任務的管理確實十分麻煩的事情,一般情況下如果要管理多執行緒的任務,我們會轉而使用 NSOpeartion。 如果問題複雜的話,我當然還是推薦使用 NSOpeartion, 但是如果我們只是為了延遲程式碼的執行,我們肯定更願意使用 DispathAfter這樣簡單的方法,這裡如果你想要在某種情況下取消未執行的操作,我們該怎麼辦呢.
我在閱讀王魏的 《Swfit Tips》時看到了他所實現的一個寫法,感覺很棒,這裡稍加修改讓它更好用一點。
import Foundation
typealias Task = (_ cancel: Bool) -> ()
@discardableResult func delay(_ time: TimeInterval, task: @escaping () -> ()) -> Task?{
func dispatch_later(block: @escaping () -> ()) {
let t = DispatchTime.now() + time
DispatchQueue.main.asyncAfter(deadline: t, execute: block)
}
var closure: (() -> Void)? = task
var result: Task?
let delayedClosure: Task = {
cancel in
if let closure = closure {
if !cancel {
DispatchQueue.main.async(execute: closure)
}
}
closure = nil
result = nil
}
result = delayedClosure
dispatch_later {
if let result = result {
result(false)
}
}
return result
}
func cancel(_ task: Task?) {
task?(true)
}
複製程式碼
使用起來也是很簡單,如下
let a = delay(4) {
print("hello one !")
}
let b = delay(6) {
print("hello two !")
}
delay(5) {
cancel(a)
cancel(b)
}
複製程式碼
這裡, 我們在5秒後,同時取消了a和b,但是a在4秒後就已經執行了,而b將會在執行前被取消。所以你只能看到列印結果 "hello one !"