杀死iOS中dispatch_async队列中的项目

时间:2012-03-03 13:11:36

标签: objective-c ios5 grand-central-dispatch

我使用dispatch_async在后台运行一堆项目,有时我想杀死队列中的内容 - 这可能吗?例如,此代码在视图上运行,然后用户返回屏幕。无论后退导航如何,所有这些已触发的操作都会继续运行。理想情况下,我想通过运行来杀死这些项目:

dispatch_async(dispatch_get_global_queue(2, 0), ^{
        for (int i=0; i<[self.manufacturers count]; i++) {
            NSString *manufacturerID = [[[self.manufacturers objectAtIndex:i] ManufacturerID] stringValue];
            [self doSync:manufacturerID withIndex:i setTimer:YES];
        }
    });

如果我创建一个队列并对其进行命名,然后在视图的dealloc上释放它,则会调用它们仍然继续运行。

2 个答案:

答案 0 :(得分:14)

调度队列中没有明确规定终止。为了做到这一点,测试逃逸位置以确定终止是有点常见的。基本上,它是一个信号量。

NSOperationQueue(更高级别的抽象,但仍在下面使用GCD构建)确实支持取消操作。因此,例如,您可以创建一系列NSOperations并将它们添加到NSOperationQueue,然后在您不需要它时将-cancelAllOperations发送到队列。

您选择的许多架构将取决于其中有多少架构正在运行以及它们是否具有不同的触发器。在这些实现中,NSOperation可能是“最干净”的解决方案,因为您有一个任意队列,您可以监视要完成的操作,还可以取消未完成的操作。进一步降低黑客的规模将是一个不稳定的位置,每个块都在一个紧密的循环内观察,以确定它们是否会过早完成。对于相同的基本功能,进一步向下将是一个全局变量。

最后,即使是NSOperation的实现也需要进行测试,以便在一致的位置退出(因为只是杀死一个线程可能会导致在分配/重新训练中运行的数据不一致)。

答案 1 :(得分:2)

执行此操作的最佳方法是创建自己的并发队列(不使用其中一个全局队列),然后在要停止处理队列时调用队列上的dispatch_suspend()。那时请阅读:Dispatch queues: How to tell if they're running and how to stop them

使用取消标志将允许您恢复队列,以便在您再次恢复时,所有剩余的块基本上都退出(在执行任何需要执行的内存管理之后,如释放资源)。您也可以在恢复后立即调度REPlease()队列。