2011-12-25 35 views
2

比方说,我在写我自己的函数,它在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; 
} 

正如你所看到的,我有两个问题,它们都包含在上面的代码中。

回答

7

问题1:在上面把它保留下来,并释放它以后会是线程安全的,在那里你会被从一个线程和另一个线程释放数据的所有权最终叫的情况下的唯一原因,但不会有帮助:即使你保留了这个对象,释放可能会在这之前发生,甚至在你被调用之前发生,在这种情况下,问题仍然会发生,你只会变得更加罕见。所以我说不用担心。

问题2:重命名你的函数CreateDataByTransformingData。然后,根据CF内存管理rules,你的函数返回调用者必须释放的所有权。

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

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

+0

谢谢,但看看在SecTransform.h(在Security.framework)的SecTransformExecute功能。该函数返回一个对象,并且名称中没有任何“创建”或“复制”。尽管如此,它还是会返回一个对象,这意味着它需要一个CFRelease对吧?那里发生了什么? – pf85 2011-12-25 18:40:54

+2

@ pf85:根据CF内存管理规则(http://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html)和隐式地由SecTransform头实施例中,不支持任何,你不需要释放它。 (这可能是值得在乐器中验证这一点的。)至于它如何被释放,转换释放它的一种可能性是当它被释放或再次执行。另一个是它使用autorelease技巧。 – 2011-12-25 18:53:14

+0

奇怪的是,如果我没有CFRelease从SecTransform返回的对象,应用程序泄漏非常严重。所以这是框架中的一个“错误”,或者是方法的错误名称,对吧? – pf85 2011-12-26 14:18:23