我正在阅读关于“调度队列的内存管理”的苹果文档:
即使您实现了垃圾收集的应用程序,您仍必须保留并释放调度队列和其他调度对象。 Grand Central Dispatch不支持回收内存的垃圾收集模型。
我知道ARC不是垃圾收集器,但我想确定我不需要dispatch_retain和dispatch_release我的dispatch_queue_t
答案 0 :(得分:232)
现在是长篇大论......
您需要在队列中使用dispatch_retain
和dispatch_release
。 ARC不管理它们。
ARC将为您管理您的队列。如果启用ARC,则不需要(也不能)使用dispatch_retain
或dispatch_release
。
从iOS 6.0 SDK和Mac OS X 10.8 SDK开始,每个调度对象(包括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.
这意味着您可以将您的队列存储在NSArray
或NSDictionary
中,或存储在strong
,weak
,unsafe_unretained
之一的属性中, assign
或retain
个属性。这也意味着如果从块中引用队列,该块将自动保留队列。
如果如果您的部署目标至少是iOS 6.0 或Mac OS X 10.8,并且您已启用ARC ,那么ARC将保留并释放您的队列和编译器将标记任何使用dispatch_retain
或dispatch_release
作为错误的尝试。
如果您的部署目标至少是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
或者您可以在构建设置中添加OS_OBJECT_USE_OBJC=0
作为预处理器宏。如果您将OS_OBJECT_USE_OBJC
设置为0
,ARC将不为您保留或释放您的队列,您必须自己使用dispatch_retain
和{{ 1}}。
答案 1 :(得分:23)
在此处进行跟进...如果您的最低部署目标是iOS 6,则ARC现在可以管理它们。