14

(但这个问题完全不同)

这个非 ARC 代码示例设置了一个基于 GCD 的计时器,并为 dispatch_source_t 对象调用 dispatch_release:

    __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);
    }

我了解到您不必在 ARC 下释放队列对象。但是像调度源这样的其他 GCD 对象呢?

4

2 回答 2

10

不,前提是您的部署目标是 iOS 6.0 或 Mac OS X 10.8 或更高版本,如此所述。

所有 GCD 对象都由 ARC 管理,因此您无需显式管理它们的内存。为真的dispatch_queue_t也适用于所有其他 GCD 对象。

这记录在<os/object.h>的定义正上方OS_OBJECT_HAVE_OBJC_SUPPORT

默认情况下,使用 Objective-C 编译器构建时,libSystem 对象(如 GCD 和 XPC 对象)被声明为 Objective-C 类型。这允许他们参与 ARC、Blocks 运行时的 RR 管理和静态分析器的泄漏检查,并使他们能够添加到 Cocoa 集合中。

-DOS_OBJECT_USE_OBJC=0您还可以使用编译器标志选择退出此行为。

于 2013-10-19T20:26:07.223 回答
1

这是要添加到代码中的编译器指令。

// 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
于 2015-07-07T21:18:57.203 回答