Core Foundation对象和保留/释放消息

bre*_*1nt 2 cocoa memory-management objective-c core-foundation

假设我们有一些Core Foundation对象,例如CGColorRef,添加到NSArray这样的对象:

CGColorRef color = ...;
NSArray *array = [NSArray arrayWithObject:(id)color];
Run Code Online (Sandbox Code Playgroud)

由于数组保留其内容,因此color收到retain消息(不是CFRetain()吗?).从内存管理的角度来看,在这种情况下会发生什么?

Pet*_*sey 10

来自Core Foundation Design Concepts:

从示例的内存管理功能和方法也需要注意互换,你可以使用CFRelease一个可可对象,releaseautorelease用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,但不能调用CF函数NULL(您将崩溃).Quartz有一些特定于类的函数,比如CGContextRetain/ Release,包括一个NULL检查; 无论你想使用它们还是总是自己做NULL检查都是一种风格问题.
  • CF的保留和释放功能,垃圾收集下工作,而retainrelease消息是无操作(好像送到nil).不要紧,除非你在GC'd Mac应用程序,在这种情况下,你将需要使用工作CFRetain,并CFRelease在CF对象.
  • 同样,根据ARC,retainrelease消息将是非法的和CF对象将不会被自动引用计数.您将需要在CF对象上使用CFRetainCFRelease.
  • 正如文档所述,集合总是做正确的事情.通常,这意味着强有力的参考.在GC之外,这意味着集合(数组,字典等)将保留并释放其对象,无论是自动(通过赋值,如果其代码是ARCified)还是手动(通过显式retainrelease消息).