直到您可以取消排队的GCD块– Christian Tietze –中

今天,我了解到您可以使用新的dispatch_block_cancel(从OS X 10.10 / iOS 8.0开始提供)取消延迟的dispatch_block_t。 感谢Matt的帖子—这是一个Swift示例:

 让工作= dispatch_block_create(0){print(“ Hello!”)} 

#10s后执行
让delayTime = dispatch_time(DISPATCH_TIME_NOW,Int64(10 * Double(NSEC_PER_SEC)))
dispatch_after(delayTime,dispatch_get_main_queue(),工作)

dispatch_block_cancel(工作)
#永远不会打印“你好!”

注意:如果正在执行该块,取消将不起作用。

如果我知道此API存在,那么我可能不会在Move!中使用下面非常麻烦的方法。

可取消延迟块的超古旧版本

出于历史目的,这是可取消调度块的改编,您可能会在互联网上找到我曾经为Swift改编的代码:

  typealias CancelableDispatchBlock =(取消:Bool)->虚空 

func dispatch(cancelableBlock块:dispatch_block_t,atDate日期:NSDate)-> CancelableDispatchBlock? {

//对同一块句柄使用两个指针
//块引用本身。
var cancelableBlock:CancelableDispatchBlock? =无

让delayBlock:CancelableDispatchBlock = {在

如果!cancel {
dispatch_async(dispatch_get_main_queue(),阻止)
}

cancelableBlock =无
}

cancelableBlock = delayBlock

让间隔= Int64(date.timeIntervalSinceNow)
让延迟=间隔* Int64(NSEC_PER_SEC)

dispatch_after(dispatch_walltime(nil,delay),dispatch_get_main_queue()){

守卫let cancelableBlock = cancelableBlock else {return}

cancelableBlock(cancel:false)
}

返回cancelableBlock
}

func cancelBlock(block:CancelableDispatchBlock?){

守卫let block =阻止else {return}

阻止(取消:true)
}

诀窍是这样的:延迟块delayBlock:CancelableDispatchBlock捕获其上下文,其中包括对cancelableBlock的引用-但尚未设置。 然后,将参考点指向delayBlock本身。

但是,实际取消是伪造的。 该块仍被调用。 但是,如果cancel参数为true,它将提前中止。

通过Christian Tietze的工作日志 http://ift.tt/1sIMLpI