objective-c – 如何“突破”dispatch_apply()?

有没有办法模拟 dispatch_apply()块中的break语句?

例如,我看到处理枚举块的每个Cocoa API都有一个“停止”参数:

[array enumerateObjectsUsingBlock:^(id obj,NSUInteger i,BOOL *stop) {
    if ([obj isNotVeryNice]) {
        *stop = YES; // No more enumerating!
    } else {
        NSLog(@"%@ at %zu",obj,i);
    }
}];

GCD有类似的东西吗?

解决方法

根据设计,dispatch _ *()API没有取消的概念.这样做的原因是因为几乎普遍认为你的代码保持了何时停止或不停止的概念,因此,也支持dispatch _ *()中API将是冗余的(并且冗余会带来错误).

因此,如果您想要“提前停止”或以其他方式取消调度队列中的待处理项目(无论它们如何排队),您可以通过与允许您取消的排队块共享一些状态来实现.

if (is_canceled()) return;

要么:

__block BOOL keepGoing = YES;
dispatch_*(someQueue,^{
    if (!keepGoing) return;
    if (weAreDoneNow) keepGoing = NO;
}

请注意,enumerateObjectsUsingBlock:和enumerateObjectsWithOptions:usingBlock:都支持取消,因为该API的角色不同.即使枚举块的实际执行可能完全并发,取决于选项,对枚举方法调用也是同步的.

因此,设置* stopFlag = YES会导致枚举停止.但是,它并不保证它会在并发情况下立即停止.实际上,枚举可以在停止之前执行一些已经排队的块.

(人们可能会简单地认为返回BOOL以指示枚举是否应该继续更合理.这样做会要求同步执行枚举块,即使在并发情况下也是如此,以便可以检查返回值.这样效率会大大降低.)

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...