iOS-SwiftiOS精華闻道者(九月份)

GCD延迟执行如何在中途取消

2017-09-04  本文已影响412人  SSBun

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 !"

End

上一篇 下一篇

猜你喜欢

热点阅读