ARC是否支持调度队列?

我正在阅读有关“调度队列的内存pipe理”的苹果文档:

即使您实施垃圾收集应用程序,您仍然必须保留并释放您的派遣队列和其他派遣对象。 Grand Central Dispatch不支持用于回收内存的垃圾回收模型。

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

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

而现在的长答案…

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

您需要在您的队列上使用dispatch_retaindispatch_release 。 ARC不pipe理它们。

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

ARC将为您pipe理您的队列。 如果启用ARC,则不需要(也不能)使用dispatch_retaindispatch_release

细节

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

  * 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 (eg 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. 

这意味着您可以将您的队列存储在NSArrayNSDictionary ,或者存储在具有strongweakunsafe_unretainedassignretain属性之一的属性中。 这也意味着,如果从块中引用您的队列,块将自动保留该队列。

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

如果您的部署目标至less为iOS 6.0或Mac OS X 10.8,并且您已禁用ARC ,则必须通过调用dispatch_retaindispatch_release手动保留并释放队列, 通过发送队列retainrelease消息(如[queue retain][queue release] )。

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

 #define OS_OBJECT_USE_OBJC 0 

或者您可以在您的构build设置中添加OS_OBJECT_USE_OBJC=0作为预处理器macros。 如果将OS_OBJECT_USE_OBJC设置为0 ,则ARC 不会为您保留或释放您的队列,您将必须使用dispatch_retaindispatch_release自己执行此操作。

只是在这里跟进…如果您的最低部署目标是iOS 6,ARC现在pipe理它们。