在Core Foundation中保留和"自动释放"

pf8*_*f85 2 c objective-c core-foundation

假设我正在编写自己的函数,该函数接收CFDataRef对象,对其执行某些操作,并返回另一个CFDataRef对象:

CFDataRef transformData(CFDataRef inData)
{
  //Question 1: Should I call CFRetain(data) here to make sure it doesn't
  //go away? (This of course would involve releasing data just before returning
  //from this function, or as soon as I no longer need data.)

  CFDataRef outData;

  //Somehow produce the new outData from inData (and assume we are the
  //owner of outData, since we created it right here).

  //Question 2: What, if anything, should I do with outData before
  //returning it? I'm unsure of this, because CF doesn't have any
  //autoreleasing mechanism.

  return outData;
}
Run Code Online (Sandbox Code Playgroud)

如您所见,我有两个问题,它们包含在上面的代码中.

Pet*_*sey 7

对于问题1:将其保留在顶部并稍后将其释放的唯一原因是线程安全,如果您从一个线程调用而另一个线程释放数据的最后一个所有权,但这将无济于事:即使您保留了对象,也可能在此之前,甚至在您被调用之前发布,在这种情况下,问题仍然会发生,而您只是变得更加罕见.所以我说不要担心.

问题2:将您的功能重命名为CreateDataByTransformingData.然后,根据CF内存管理规则,您的函数返回调用者必须释放的所有权.

问题2的替代解决方案:转发NSData *并向其发送autorelease消息.(这要求您使用MRC,而不是ARC,至少对于此模块/类.)

[已添加2013-11-01]备用备用解决方案:需要OS X 10.9或更高版本并使用CFAutorelease功能.

  • @ pf85:根据CF内存管理规则(http://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html)并且SecTransform标头示例隐式支持,不,你不需要发布它.(它可能值得在仪器中验证这一点.)至于它是如何被释放的,转换在释放它或再次执行它时释放它的一种可能性.另一个是它使用autorelease技巧. (2认同)