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