14

(But this question is totally different)

This non-ARC code example sets up a GCD-based timer and it calls dispatch_release for a dispatch_source_t object:

    __block BOOL done = NO;
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
    if (timer) {
        uint64_t milliseconds = 100ull;
        uint64_t interval = milliseconds * NSEC_PER_MSEC;
        uint64_t leeway = 10ull * NSEC_PER_MSEC;
        __block typeof(self) _self = self;

        dispatch_source_set_timer(timer, dispatch_walltime(NULL, 0), interval, leeway);
        dispatch_source_set_event_handler(timer, ^{
            //[_progressBar setProgress:exportSession.progress animated:YES];
            if (done) {
                dispatch_source_cancel(timer);
                dispatch_release(timer);
                _self.exportingMovieLabel.hidden = YES;
                _self.exportingProgress.hidden = YES;
            }
        });

        dispatch_resume(timer);
    }

I learned that you do not have to release queue objects under ARC. But other GCD objects like a dispatch source?

openfrog
  • 40,201
  • 65
  • 225
  • 373
  • 1
    The claimed "duplicate question" is not even close. The answers specifically talk about GCD queues. This question specifically asks if this is true for other GCD objects. – openfrog Oct 18 '13 at 16:35
  • 2
    Try it. The compiler won't let you if it's not necessary (it's not). – Catfish_Man Oct 18 '13 at 16:41
  • 1
    In my experience, the Apple documentation always mentions that you need to manage releases of it's necessary. Usually, there are specific functions to do the releasing. In this case, reading the docs, it looks like it depends on the use whether you need to manage the release yourself. I take this to mean if you use dispatch_retain and hold onto a pointer, you will need to release it yourself. I've not used this function, though, so take this with a grain of salt. – Victor Engel Oct 18 '13 at 17:44
  • 4
    To clear this up, yes, ARC handles other GCD objects, not just queues, when deployed to OS version as described in the duplicate question. Look at os/object.h for details. Notably, "By default, libSystem objects such as GCD and XPC objects are declared as Objective-C types when building with an Objective-C compiler. This allows them to participate in ARC". There's a #define for OS_OBJECT_HAVE_OBJC_SUPPORT you can use to check (at compile time) whether ARC handles GCD (and XPC) objects. The accepted answer for the duplicate question mentions all of this. – Andrew Madsen Oct 18 '13 at 18:36

2 Answers2

10

No, provided that your deployment target is iOS 6.0 or Mac OS X 10.8 or later, as explained here.

All GCD objects are managed by ARC, so you don't need to explicitly manage their memory. What is true for dispatch_queue_t also applies to all the other GCD objects.

This is documented in <os/object.h> right above the definition of OS_OBJECT_HAVE_OBJC_SUPPORT.

By default, libSystem objects such as GCD and XPC objects are declared as Objective-C types when building with an Objective-C compiler. This allows them to participate in ARC, in RR management by the Blocks runtime and in leaks checking by the static analyzer, and enables them to be added to Cocoa collections.

You can also opt-out from this behavior using the -DOS_OBJECT_USE_OBJC=0 compiler flag.

Community
  • 1
  • 1
Gabriele Petronella
  • 106,943
  • 21
  • 217
  • 235
1

Here is compiler directive to add to your code.

// If GCD objects are treated as Objective C object then we do not need to call dispatch_release on those GCD object.
// Checking if OS_OBJECT_HAVE_OBJC_SUPPORT == 0 ensures we are only releasing GCD objects when they are NOT being treated as Objective C objects.
#if OS_OBJECT_HAVE_OBJC_SUPPORT == 0
    dispatch_release(timer);
#endif
Kris Subramanian
  • 1,850
  • 18
  • 15