我是否需要在DispatchQueue.main.async中使用autoreleasepool块

时间:2017-01-22 16:34:59

标签: ios swift multithreading

在Xcode 8.2.1中使用swift 3作为iOS应用程序。

我知道在新线程上调度某些处理时我需要一个autoreleasepool块。但是在调度主线程时需要它吗?

假设我们在主线程上并执行以下操作:

    DispatchQueue.global(qos: .background).async {
        autoreleasepool {
            //***** do something in the background
        } // autoreleasepool

        DispatchQueue.main.async {
            //***** do something on the main thread when background job is done
            //***** does this something need to be enclosed in an autoreleasepool block ?
        } // DispatchQueue.main.async

    } // DispatchQueue.global

2 个答案:

答案 0 :(得分:2)

您不能使用GCD(dispatch系列函数)创建新线程。这些是已经存在的系统队列,您不需要额外的自动释放池。

如果您要在Swift中手动使用NSThreadThread,那么您将不得不担心这一点,但通常您不需要这个甚至是相对高级的后台处理。

答案 1 :(得分:2)

DispatchQueue具有“自动释放频率”属性,该属性决定每个工作项是否自动被autorelease{}包围。它记录在dispatch/queue.h中,而不是Apple文档中,因此我无法链接到它。附加标题的屏幕截图。

  • DispatchQueue.main具有自动释放频率.workitem(这意味着自动释放每个dispatch_async)
  • DispatchQueue.global将其设置为.never(永远不会自动释放;这取决于您)
  • DispatchQueue.init创建一组.inherit。默认情况下,新队列以全局队列为目标,这意味着它隐式地.never

documentation screenshot of .never

请注意,此属性仅适用于.async()。如果您进行.sync(),则必须始终手动管理自动释放情况。

docu screenshot of dispatch_sync

要回答您的问题:否。在主线程上,您不必用autorelease{}包装异步块。对于任何其他队列,您都需要设置属性或手动包装在autorelease{}中。

如果存在自动释放的风险,我建议不要直接调度到DispatchQueue.global,因为这可能会泄漏或最终导致永不清空的池。而是使用明确的自动释放池策略创建自己的队列。