Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS bridge vs bridge_transfer

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?

like image 371
Rinat Avatar asked Mar 25 '12 10:03

Rinat


People also ask

What is __ Bridge_transfer?

__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.

When to use__ bridge?

__bridge is used to transfer/convert the pointer between Core Foundation and Foundation without ownership.


2 Answers

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.

like image 119
He Shiming Avatar answered Oct 08 '22 18:10

He Shiming


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.

like image 24
Pochi Avatar answered Oct 08 '22 16:10

Pochi