如何在发布时清空并完全释放大中央调度队列



我有一个对象,在初始化时使用 dispatch_queue_create 创建一个串行 GCD 队列,并在释放调用时调用dispatch_free .在对象的生存期内,调度块将添加到队列中,但是队列也会停止并使用 dispatch_suspenddispatch_resume 启动。

我的问题是,在某一时刻,对象可能会被释放,并且在释放时,为了整洁起见,我想完全删除调度队列和其中的所有dispatch_block_t对象,无论队列是否挂起。

据我了解,队列不会释放,直到不再需要"需要",因为它不再被其中的调度块保留。这让我相信,要释放队列,我必须通过允许其中的块首先执行到终止来清空它。

解决这个问题

的最简单和最强大的方法是什么?

一般来说,

这不是你应该太担心的事情。来自并发编程指南中的调度队列的内存管理:

您可以使用 dispatch_retain 和 dispatch_release 函数根据需要递增和递减引用计数。当队列的引用计数达到零时,系统会异步解除分配队列。

因此,当您调用 dispatch_release(myQueue) 时,您将降低保留计数,但队列中仍在的任何任务都将保留队列。直到这些完成,队列的保留计数才会为 0。所以你的这部分问题:

这让我相信,要释放队列,我必须通过允许其中的块首先执行到终止来清空它。

是准确的。如果您有可能不想运行的任务在队列中,请继续阅读。

如果要从代码中挂起和恢复队列,这不会导致问题 - 因为必须平衡所有挂起和恢复调用。如果您将队列置于挂起状态,您将度过一段糟糕的时光。也就是说,您还可以选择使用 dispatch_set_finalizer_f 为队列设置清理功能。这应该不是必需的,但如果您需要它,它就在那里。

现在,根据你在这里描述的内容,我建议改用NSOperation和NSOperationQueue。它是 GCD 之上的更高级别层,允许您取消任务并执行一些其他有用的操作,这些操作直接使用 GCD 很难完成。

最新更新