ARC是否支持调度队列?
我正在阅读有关“调度队列的内存pipe理”的苹果文档:
即使您实施垃圾收集应用程序,您仍然必须保留并释放您的派遣队列和其他派遣对象。 Grand Central Dispatch不支持用于回收内存的垃圾回收模型。
我知道ARC不是一个垃圾收集器,但我想确保我不需要dispatch_retain和dispatch_release我的dispatch_queue_t
简短的回答:是的,ARC保留并释放调度队列。
而现在的长答案…
如果您的部署目标低于iOS 6.0或Mac OS X 10.8
您需要在您的队列上使用dispatch_retain
和dispatch_release
。 ARC不pipe理它们。
如果您的部署目标是iOS 6.0或Mac OS X 10.8或更高版本
ARC将为您pipe理您的队列。 如果启用ARC,则不需要(也不能)使用dispatch_retain
或dispatch_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.
这意味着您可以将您的队列存储在NSArray
或NSDictionary
,或者存储在具有strong
, weak
, unsafe_unretained
, assign
或retain
属性之一的属性中。 这也意味着,如果从块中引用您的队列,块将自动保留该队列。
因此, 如果您的部署目标至less是iOS 6.0或Mac OS X 10.8,并且您启用了 ARC,则ARC将保留并释放您的队列,编译器将标记尝试使用dispatch_retain
或dispatch_release
作为错误。
如果您的部署目标至less为iOS 6.0或Mac OS X 10.8,并且您已禁用ARC ,则必须通过调用dispatch_retain
和dispatch_release
手动保留并释放队列, 或通过发送队列retain
和release
消息(如[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_retain
和dispatch_release
自己执行此操作。
只是在这里跟进…如果您的最低部署目标是iOS 6,ARC现在pipe理它们。