I\'m confused with bridge
and bridge_transfer
, is this correct?
-(void)getData{
ABAddressBookRef addressBook = ABAddressBookCreate(
One edit: I believe calling CFRelease on a nil object does cause the app to crash
Luis Oscar I'm still working out my understanding of ARC, but I believe addressBook does need CFRelease. ARC is not managing addressBook. NSArray *allPeople is being managed by ARC via the __bridge_transfer cast hint and it is being created as a copy of the original. Without the CFRelease, addressBook will leak.
If you have automatic-reference-counting (ARC) turned on, the code is correct.
There are two __bridge_transfer
in your statements. As a result, the ownership of created CFObjects will be transferred to NSObjects. If you have ARC turned on, they will be freed up automatically. If you used __bridge
instead for these 2 statements, you will need to explicitly call CFRelease
to release CFObjects created by the *Copy
API.
The __bridge
statement is also correct. Because you are referencing an NSObject in CF API. You are not transferring ownership, so that ARC will free it up.
It is very very simple, When you use ARC (automatic reference counting) the compiler will take care of counting how many objects are being pointed by your variables. When the count goes to 0 the object is automatically dealocated. SO for things that come from a low level structure, like core foundation, the compiler doesnt know what to do. So you use BRIDGE if you just want to tell the compiler "ignore this one, i will release it when i need it". or Bridge transfer if you want to say "Treat this as an object and release it when the reference goes to 0).
When you do this, you create a copy that under normal circumstances should be released by a "CFRelease":
ABAddressBookCopyArrayOfAllPeople(addressBook)
However by adding this, you are transferring the ownership to an objective-c object:
NSArray *allPeople = (__bridge_transfer NSArray*)........
So the NSArray will be managed by ARC.
Note that as JRG mentions, doing this:
CFRelease(addressBook);
Does not affect the newly created object in anyway, but instead the original one which you still have to manually release: (It's easy to tell because those methods usually have the create or copy keywords in their names)
Something that does not happen in your code but you should be careful with is that releasing core foundation objects which are NULL with CFRelease will cause an error. As Paul mentions in his comment.