ARC支持调度队列吗?

fla*_*g19 93 objective-c grand-central-dispatch automatic-ref-counting

我正在阅读关于"调度队列的内存管理"的苹果文档:

即使您实现了垃圾收集的应用程序,您仍必须保留并释放调度队列和其他调度对象.Grand Central Dispatch不支持回收内存的垃圾收集模型.

我知道ARC不是垃圾收集器,但我想确定我不需要dispatch_retain和dispatch_release我的dispatch_queue_t

rob*_*off 232

简短回答:是的,ARC保留并释放调度队列.







而现在长期回答......

如果您的部署目标低于iOS 6.0或Mac OS X 10.8

您需要在队列中使用dispatch_retaindispatch_release.ARC不管理它们.

如果您的部署目标是iOS 6.0或Mac OS X 10.8或更高版本

ARC将为您管理您的队列.您不需要(也不能)使用dispatch_retaindispatch_release启用ARC.

细节

从iOS 6.0 SDK和Mac OS X 10.8 SDK开始,每个调度对象(包括a dispatch_queue_t)也是一个Objective-C对象.这在<os/object.h>头文件中记录:

 * 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.
 *
 * NOTE: this requires explicit cancellation of dispatch sources and xpc
 *       connections whose handler blocks capture the source/connection object,
 *       resp. ensuring that such captures do not form retain cycles (e.g. by
 *       declaring the source as __weak).
 *
 * To opt-out of this default behavior, add -DOS_OBJECT_USE_OBJC=0 to your
 * compiler flags.
 *
 * This mode requires a platform with the modern Objective-C runtime, the
 * Objective-C GC compiler option to be disabled, and at least a Mac OS X 10.8
 * or iOS 6.0 deployment target.
Run Code Online (Sandbox Code Playgroud)

这意味着你可以在你的队列存储在一个NSArray或者NSDictionary,或与一个属性strong,weak,unsafe_unretained,assign,或retain属性.这也意味着如果从块中引用队列,该块将自动保留队列.

因此,如果您的部署目标至少是iOS 6.0或Mac OS X 10.8,并且您启用了 ARC,ARC将保留并释放您的队列,编译器将标记任何使用尝试dispatch_retaindispatch_release作为错误.

如果您的部署目标是至少6.0的iOS或Mac OS X 10.8,和你有ARC禁用,您必须手动保留和释放你的队列或者通过调用dispatch_retaindispatch_release,通过发送队列retainrelease消息(像[queue retain][queue release]).

为了与旧代码库兼容,您可以通过定义OS_OBJECT_USE_OBJCto 来阻止编译器将您的队列视为Objective-C对象0.例如,您可以将它放在您的.pch文件中(在任何#import语句之前):

#define OS_OBJECT_USE_OBJC 0
Run Code Online (Sandbox Code Playgroud)

或者您可以OS_OBJECT_USE_OBJC=0在构建设置中添加预处理器宏.如果你设置OS_OBJECT_USE_OBJC0,ARC将不会为你保留或释放你的队列,你必须自己使用dispatch_retaindispatch_release.

  • 这是一个有趣的边缘案例.如果您的库部署到iOS 5.1并且您的应用程序部署到6.0并且您正在使用ARC,则需要在您的5.1`dealloc`代码中对`dispatch_release`**和**`NULL`这个对象.否则,某些东西(编译器生成的代码?运行时本身?)将尝试第二次释放该对象. (3认同)

kch*_*ood 23

只需在此处跟进...如果您的最低部署目标是iOS 6,ARC现在可以管理它们.