GCD创建队列错误

时间:2013-10-15 11:56:37

标签: ios queue grand-central-dispatch

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

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; 需要,停止并释放旧队列并创建新队列

2 个答案:

答案 0 :(得分:1)

暂停队列然后丢弃对该队列的唯一引用不太可能实现您认为的应该。

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

实际上,当您执行此操作(删除对iOS 6+中已暂停队列的最后一个强引用)时,它将崩溃。也许iOS应该更优雅地处理这个问题,但是,删除你对暂停队列的最后一个引用从而无法恢复它的情况也就不足为奇了。

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

答案 1 :(得分:0)

如果你真正想要做的是在开始新的hardMethod之前取消之前的NSOperation来电,你应该真正查看明确支持取消的NSOperationQueue和{{1}}。