有没有办法实现dispatch_cancel()?

到目前为止,我已经通过了GCD的文档,但是它似乎没有dispatch_cancel(),我想用它来取消所有调度块的调用。 有没有办法实现dispatch_cancel()?

正如@HampusNilsson所提到的,你不能合理地取消在非垃圾收集环境(比如这个)中的任何飞行中的操作,因为它本质上会泄漏资源并使进程处于不确定状态。 NSOperationQueue有一个取消API,并且这个API可以用来实现取消进行中的操作,只要操作本身是协作检查标志,然后提前清理和返回。 这不是一个真正的,难以终止的。

至于取消排队但未开始的工作项目,是的, NSOperationQueue处理这个问题,但这需要额外的费用, NSOperationQueue是一个更高的抽象层次。 GCD的性能主要取决于内部使用无锁队列。 无锁队列将比基于锁的实现更快,但为了达到这个速度,需要一些权衡。 例如,我认为以无锁的方式任意改变队列以消除取消的操作会更困难。 我怀疑,将暴露的队列操作限制为“只入队”,并使工作项本身不可变(块和函数ptrs),为许多优化打开了大门,使GCD得到如此小的开销并performance得如此之好。

FWIW,通常情况下,取消操作对于在现有的GCD API之上执行是非常简单的,所以任何需要这个function的人都可以很容易地自己做(也可能以更好的方式适应他们的特定需求比通用的API将是)。 考虑下面的函数 – 它将一个块排入队列并返回一个可以稍后调用的块来取消排队操作:

 dispatch_block_t dispatch_cancelable_async(dispatch_queue_t q, dispatch_block_t b) { __block uintptr_t isCancelled = 0; dispatch_async(q, ^{ if (!isCancelled) b(); }); return [[^{ isCancelled = 1; } copy] autorelease]; } 

对于每一种情况,这都不是正确的取消方法,但这是一个不错的第一个近似值。

“使用最高级别的抽象来完成工作。” 如果你想取消, NSOperationQueue和GCD之间的开销差异不是一个重要的因素,你应该只使用NSOperationQueue 。 有些人甚至会认为在Objective-C中使用NSOperationQueue是更习惯的select。 除此之外,如图所示,在GCD之上实施不中止取消普通案例是相当微不足道的。

基于这一切,我的怀疑是在性能和​​复杂性方面取消API的构build并不是一个值得的权衡。

GCD没有实现一个取消API,因为它不是安全的(它可能会中止操作)。 如果你想取消任务,你需要通过实现一个“取消的”布尔值来自己做,并在开始时定期检查它,

从iOS 8和更高版本,您可以取消块执行
dispatch_block_cancel

 dispatch_block_t blockTask = dispatch_block_create(0,{ //do some task }); dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW,5*NSEC_PER_SEC); dispatch_after(time,dispatch_get_main_queue(),blockTask); dispatch_block_cancel(blockTask);