直到您可以取消排队的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