【问题标题】:Core Foundation objects and retain/release messages核心基础对象和保留/释放消息
【发布时间】:2011-11-27 05:04:26
【问题描述】:
假设我们有一些 Core Foundation 对象,例如 CGColorRef,它们像这样添加到 NSArray:
CGColorRef color = ...;
NSArray *array = [NSArray arrayWithObject:(id)color];
由于数组保留了它们的内容,color 会收到retain 消息(不是CFRetain(),对吗?)。从内存管理的角度来看,在这种情况下会发生什么?
【问题讨论】:
标签:
objective-c
cocoa
memory-management
core-foundation
【解决方案1】:
From Core Foundation Design Concepts:
请注意,内存管理函数和方法也是可以互换的——您可以将 CFRelease 与 Cocoa 对象一起使用,将 release 和 autorelease 与 Core Foundation 对象一起使用。
它没有特别提到retain,但在实践中,copy(各种类的CFFooCreateCopy)和description(CFCopyDescription)也是如此。最后是在使用 NSLog 和其他字符串格式化函数和方法时,如何将 CF 对象作为 %@ 格式化规范的值传递。
结果是一样的:retain 和 CFRetain 一样,release 和 CFRelease 一样,等等。
需要注意的几点:
- 在iOS 7 和OS X 10.9 之前,NSObject 的
autorelease 方法没有CF 对应函数。 (7 和 10.9 带来了 CFAutorelease 函数。)如果您不使用 ARC,那么,如上面引用的文档中所述,您可以将 autorelease 发送到 CF 对象,它的工作原理与 NSObject 相同.
- 您可以向
nil 发送消息,但您不能在NULL 上调用CF 函数(您会崩溃)。 Quartz 有一些特定于类的函数,例如CGContextRetain/Release,其中包括NULL 检查;无论您是想使用它们还是总是自己做NULL 检查,都是风格问题。
- CF 的保留和释放功能在垃圾收集下工作,而
retain 和release 消息是无操作的(就像发送到nil)。没关系,除非您正在使用经过 GC 处理的 Mac 应用,在这种情况下,您需要在 CF 对象上使用 CFRetain 和 CFRelease。
- 同样,在 ARC 下,
retain 和 release 消息将是非法的,并且 CF 对象不会被自动引用计数。您需要在 CF 对象上使用 CFRetain 和 CFRelease。
- 集合总是做正确的事,如文档所述。通常,这意味着强参考。在 GC 之外,这意味着集合(数组、字典等)将保留和释放其对象,无论是自动(通过赋值,如果其代码是 ARCified)还是手动(通过显式
retain 和 release 消息)。