I'm confused with bridge
and bridge_transfer
, is this correct?
-(void)getData{ ABAddressBookRef addressBook = ABAddressBookCreate(); NSArray *allPeople = (__bridge_transfer NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook); NSString *name; for ( int i = 0; i < [allPeople count]; i++ ) { name = (__bridge_transfer NSString *) ABRecordCopyValue((__bridge ABRecordRef)[allPeople objectAtIndex:i], kABPersonFirstNameProperty); } CFRelease(addressBook); allPeople = nil; }
Is there anyone who can explain me how to use them?
__bridge_transfer or CFBridgingRelease moves a non-Objective-C pointer to Objective-C and also transfers ownership to ARC. ARC is responsible for relinquishing ownership of the object.
__bridge is used to transfer/convert the pointer between Core Foundation and Foundation without ownership.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With