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.
Note that this attribute only applies to .async(). If you do .sync(), you must always manually manage the autorelease situation.

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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With