简体   繁体   中英

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

Using swift 3 in Xcode 8.2.1 for an iOS App.

I understand that I need an autoreleasepool block when dispatching some processing on a new thread. 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. It's documented in dispatch/queue.h and not in Apple's documentation, so I can't link to it; attaching screenshots from the headers.

  • DispatchQueue.main has autorelease frequency .workitem (which means autorelease each dispatch_async)
  • DispatchQueue.global has it set to .never (never autorelease automatically; it's up to you)
  • DispatchQueue.init creates one set to .inherit . By default, a new queue targets the global queue, which means it's implicitly .never .

.never的文档截图

Note that this attribute only applies to .async() . If you do .sync() , you must always manually manage the autorelease situation.

dispatch_sync的docu屏幕截图

To answer your question: No. On main thread, you don't have to wrap your async block with autorelease{} . For any other queue, you either need to set the attribute or manually wrap in 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. Instead, create your own queues with explicit autorelease pool policy.

You don't create new threads using GCD ( dispatch family of functions). 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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