简短回答:是的,ARC会保留和释放调度队列。
长篇回答如下:
如果您的部署目标低于iOS 6.0或Mac OS X 10.8
您需要在队列上使用dispatch_retain
和dispatch_release
,因为ARC不会管理它们。
如果您的部署目标是iOS 6.0或Mac OS X 10.8或更高版本
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
语句之前)。
或者您可以在构建设置中添加OS_OBJECT_USE_OBJC=0
作为预处理器宏。如果将OS_OBJECT_USE_OBJC
设置为0
,ARC将不会为您保留或释放队列,您需要使用dispatch_retain
和dispatch_release
自行处理。
dealloc
代码中同时使用dispatch_release
和NULL
对象。否则,某些东西(编译器生成的代码?运行时本身?)将尝试第二次释放对象。 - Steven Fisher