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
?
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.
Another small point that no-one has mentioned yet, some CF classes have a "toll-free bridge" with their NS counterpart.
CFString
andNSString
,CFArray
andNSArray
are both examples. This is relevant as you can just userelease
with these classes.See this other StackOverflow question for more information.
For ARC you can use.
"__bridge_transfer" will transfer the ownership to ARC and therefore you don't need any further release call.
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.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 callCFRetain
to take ownership (necessarily requiring a subsequentCFRelease
to relinquish that new ownership). These rules, as taken from the Memory Management Programming Guide for Core Foundation are:In your example, both the
addressBook
and thepeopleArray
must be released. Since there is noautorelease
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 toNSCFArray
, an Objective-C object that inherits fromNSObject
. You can thus castpeopleArray
to anNSArray*
andautorelease
that, if you need to return it from a function/method: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.