Cancel a timed event in Swift?

前端 未结 7 1934
说谎
说谎 2020-11-27 15:36

I want to run a block of code in 10 seconds from an event, but I want to be able to cancel it so that if something happens before those 10 seconds, the code won\'t run after

7条回答
  •  爱一瞬间的悲伤
    2020-11-27 16:12

    Try this (Swift 2.x, see David's answer below for Swift 3):

    typealias dispatch_cancelable_closure = (cancel : Bool) -> ()
    
    func delay(time:NSTimeInterval, closure:()->()) ->  dispatch_cancelable_closure? {
    
        func dispatch_later(clsr:()->()) {
            dispatch_after(
                dispatch_time(
                    DISPATCH_TIME_NOW,
                    Int64(time * Double(NSEC_PER_SEC))
                ),
                dispatch_get_main_queue(), clsr)
        }
    
        var closure:dispatch_block_t? = closure
        var cancelableClosure:dispatch_cancelable_closure?
    
        let delayedClosure:dispatch_cancelable_closure = { cancel in
            if let clsr = closure {
                if (cancel == false) {
                    dispatch_async(dispatch_get_main_queue(), clsr);
                }
            }
            closure = nil
            cancelableClosure = nil
        }
    
        cancelableClosure = delayedClosure
    
        dispatch_later {
            if let delayedClosure = cancelableClosure {
                delayedClosure(cancel: false)
            }
        }
    
        return cancelableClosure;
    }
    
    func cancel_delay(closure:dispatch_cancelable_closure?) {
        if closure != nil {
            closure!(cancel: true)
        }
    }
    
    // usage
    let retVal = delay(2.0) {
        println("Later")
    }
    delay(1.0) {
        cancel_delay(retVal)
    }
    

    From Waam's comment here: dispatch_after - GCD in swift?

提交回复
热议问题