简体   繁体   English

我是否需要DispatchQueue.main.async中的autoreleasepool块

[英]Do I need an autoreleasepool block inside a DispatchQueue.main.async

Using swift 3 in Xcode 8.2.1 for an iOS App. 在iOS应用程序的Xcode 8.2.1中使用swift 3。

I understand that I need an autoreleasepool block when dispatching some processing on a new thread. 我知道在新线程上分派一些处理时需要一个autoreleasepool块。 But is it needed when dispatching back on main thread ? 但是在主线程上分派时是否需要?

Suppose we are on the main thread and do the following: 假设我们在主线程上并执行以下操作:

    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

DispatchQueue has an "autorelease frequency" attribute, which decides if every workitem is automatically surrounded by autorelease{} or not. DispatchQueue具有“自动释放频率”属性,该属性决定是否每个工作项都自动被autorelease{}包围。 It's documented in dispatch/queue.h and not in Apple's documentation, so I can't link to it; 它记录在dispatch/queue.h而不是在Apple文档中,因此我无法链接到它。 attaching screenshots from the headers. 附加标题的屏幕截图。

  • DispatchQueue.main has autorelease frequency .workitem (which means autorelease each dispatch_async) DispatchQueue.main具有自动释放频率.workitem (这意味着自动释放每个dispatch_async)
  • DispatchQueue.global has it set to .never (never autorelease automatically; it's up to you) DispatchQueue.global将其设置为.never (从不自动释放;由您决定)
  • DispatchQueue.init creates one set to .inherit . DispatchQueue.init.inherit创建一个集合。 By default, a new queue targets the global queue, which means it's implicitly .never . 默认情况下,新队列以全局队列为目标,这意味着它隐式为.never

.never的文档截图

Note that this attribute only applies to .async() . 请注意,此属性仅适用于.async() If you do .sync() , you must always manually manage the autorelease situation. 如果执行.sync() ,则必须始终手动管理自动释放情况。

dispatch_sync的docu屏幕截图

To answer your question: No. On main thread, you don't have to wrap your async block with autorelease{} . 要回答您的问题:否。在主线程上,您不必使用autorelease{}包装异步块。 For any other queue, you either need to set the attribute or manually wrap in autorelease{} . 对于任何其他队列,您都需要设置属性或手动包装在autorelease{}

I recommend never dispatching directly to DispatchQueue.global if there's a risk something would be autoreleased, as that would either leak or end up in a never-emptied pool. 如果可能会自动释放某些东西,我建议不要直接DispatchQueue.globalDispatchQueue.global ,因为这可能会泄漏或最终导致一个永不清空的池。 Instead, create your own queues with explicit autorelease pool policy. 而是使用明确的自动释放池策略创建自己的队列。

You don't create new threads using GCD ( dispatch family of functions). 您不会使用GCD( dispatch功能家族)创建新线程。 Those are system queues that already exist and you don't need additional autorelease pools for them. 这些是已经存在的系统队列,您不需要其他的自动释放池。

If you were to manually use NSThread or Thread in Swift, then you would have to worry about that, but generally you don't need this for even relatively advanced background processing. 如果您要在Swift中手动使用NSThreadThread ,那么您将不必担心,但是通常您甚至不需要相对高级的后台处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM