0

我用过GCD。弧项目。当第二次调用此代码时,项目崩溃...

if (self.queue)
{
        dispatch_suspend(self.queue);
        self.queue = NULL;
}    
self.queue = dispatch_queue_create("com.myapp.blabla.queue", NULL);
dispatch_async(self.queue, ^{
        [self hardMethod];
});

崩溃的字符串self.queue = NULL; 需要,停止并释放旧队列并创建新队列

4

2 回答 2

1

挂起一个队列然后丢弃对该队列的唯一引用不太可能达到您认为的效果。

从理论上讲,您会期望泄漏:当您调用dispatch_suspend当前正在执行的任务时,将完成,但任何挂起的任务都将被挂起(并保持对队列的强引用)。更糟糕的是,因为您放弃了对队列的唯一引用,您将永远无法恢复队列并释放这些资源。从理论上讲,您会泄漏队列和任何排队的调度块(以及这些排队的块具有强引用的任何对象)。

在实践中,当你这样做(在 iOS 6+ 中删除你对挂起队列的最后一个强引用)时,它会崩溃。也许 iOS 真的应该更优雅地处理这个问题,但尽管如此,删除最后一个对挂起队列的引用,从而无法恢复它的场景会出现问题也就不足为奇了。

底线,不要暂停队列,然后尝试释放它。如果你想取消你的后台任务,你可能想使用操作队列而不是 Grand Central Dispatch。操作队列更优雅地处理可取消的操作,如果您使用NSOperation子类,您甚至可以编写代码来处理可能正在进行的操作的取消。

于 2013-10-15T13:12:14.303 回答
0

如果您真正想要做的是hardMethod在开始新的呼叫之前取消之前的呼叫,您应该真正检查一下NSOperation并且NSOperationQueue明确支持取消。

于 2013-10-15T12:41:52.330 回答