Swift GCD中取消一个正在执行的Block

Swift GCD中没有原生支持取消等的操作,这些操作就需要我们自己动手去实现。

Playground中想要支持异步,需要将needsIndefiniteExecution参数设置为true

import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true

下面就是取消block的demo:

typealias Task = (_ cancel: Bool) -> Void

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 internalClosure = closure {
            if (cancel == false) {
                DispatchQueue.main.async(execute: internalClosure)
            }
        }
        closure = nil
        result = nil
    }
    
    result = delayedClosure
    dispatch_later {
        if let delayedClosure = result {
            delayedClosure(false)
        }
    }
    
    return result
}

func cancel(_ task: Task?) {
    task?(true)
}

let task = delay(2) { print("两秒后输出") }

参考:

  • ObjC 中国 - Swifter - Swift 开发者必备 Tips

你可能感兴趣的:(Swift GCD中取消一个正在执行的Block)