Search code examples
objective-cgrand-central-dispatchdispatch-async

Do I need to Block_release dispatch_block_t which is in the dispatch_barrier_async when no ARC


Do I need to Block_release dispatch_block_t which is in the dispatch_barrier_async when no ARC ? I noticed "The barrier block to submit to the target dispatch queue. This block is copied and retained until it finishes executing, at which point it is released." in dispatch_barrier_async.

dispatch_block_t work = dispatch_block_create(0, ^{
    //...
});

if (work) {
    dispatch_barrier_async(_dispatchQueue, work);
    auto res = dispatch_block_wait(work, timeout);
    if (res) {
        // timeout, then cancel, I should release work here?
        dispatch_block_cancel(work);
    }

    Block_release(work); // do I need to release work when no ARC? the dispatch_barrier_async would release it if it's executed?
}

Solution

  • When not using ARC, yes, you have to release it. Press command+shift+o (the letter “o”, not zero) and search for dispatch_block_create to jump to the headers (or control-click on dispatch_block_create in your code and choose “Jump to Definition”), and it says:

    When not building with Objective-C ARC, must be released with a -[release] message or the Block_release() function.

    That having been said, you are already releasing the work below, so you certainly do not have to release it a second time inside that if statement.


    Unfortunately, the static analyzer (shift+command+b), which is generally excellent at these sorts of manual referencing counting issues, does not appear to identify potentially leaked dispatch_block_t instances. Still, I'd make sure you have a clean bill of health from the static analyzer.