Releasing Core Foundation object references

天涯浪子 提交于 2019-12-03 03:47:25

问题


Do I need to release a Core Foundation objects to clear up memory? And if so, how?

For example, in the code:

ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef peopleArray = ABAddressBookCopyArrayOfAllPeople(addressBook);

do I need to release peopleArray? What about addressBook?


回答1:


Yes, in CoreFoundation you have to release anything with Create or Copy in the name. You do this with CFRelease(). In your case, you should be releasing both the array and the address book references.




回答2:


The rules for memory management in Core Foundation are similar to those in Cocoa: if the method that returns a reference contains the words "create" or "copy", you own the reference and must call CFRelease() on that reference to relinquish ownership. Otherwise, you do not own the reference and must call CFRetain to take ownership (necessarily requiring a subsequent CFRelease to relinquish that new ownership). These rules, as taken from the Memory Management Programming Guide for Core Foundation are:

  • If you create an object (either directly or by making a copy of another object—see “The Create Rule”), you own it.
  • If you get an object from somewhere else, you do not own it. If you want to prevent it being disposed of, you must add yourself as an owner (using CFRetain).
  • If you are an owner of an object, you must relinquish ownership when you have finished using it (using CFRelease).

In your example, both the addressBook and the peopleArray must be released. Since there is no autorelease equivalent in Core Foundation, if you are returning the a reference from a method, return the array without releasing it. You should (unless you're being evil) then include "create" in the method name to indicate to the caller that they now own a reference to the returned object. In this case, CFArray is toll-free bridged to NSCFArray, an Objective-C object that inherits from NSObject. You can thus cast peopleArray to an NSArray* and autorelease that, if you need to return it from a function/method:

return [(NSArray*)peopleArray autorelease];

Note that this only works for toll-free bridged classes. My understanding is that it's rather difficult to make your own toll-free bridged classes and only the primitive (string, array, etc.) CF classes are toll-free bridged, so this approach won't work always. Finally, if you can avoid using autorelease (i.e. you can make your memory management more explicit), that's probably always a good thing.




回答3:


Another small point that no-one has mentioned yet, some CF classes have a "toll-free bridge" with their NS counterpart. CFString and NSString, CFArray and NSArray are both examples. This is relevant as you can just use release with these classes.

See this other StackOverflow question for more information.




回答4:


I would suggest reading Apple's guide on Core Foundation memory management for an in-depth discussion of this. They have a similar guide for general Cocoa memory management as well.

To release a CF object, you would call the CFRelease function.




回答5:


For ARC you can use.

return (__bridge_transfer NSArray*)peopleArray;

"__bridge_transfer" will transfer the ownership to ARC and therefore you don't need any further release call.



来源:https://stackoverflow.com/questions/870243/releasing-core-foundation-object-references

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!