Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
like image 837
KerCodex Avatar asked Jan 22 '17 16:01

KerCodex


1 Answers

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.

documentation screenshot of .never

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

docu screenshot of dispatch_sync

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.

like image 171
nevyn Avatar answered Sep 29 '22 16:09

nevyn