I agree that the description is confusing. Since I just grasped them, I'll try to summarize:
(__bridge_transfer <NSType>) op
or alternatively CFBridgingRelease(op)
is used to consume a retain-count of a CFTypeRef
while transferring it over to ARC. This could also be represented by id someObj = (__bridge <NSType>) op; CFRelease(op);
(__bridge_retained <CFType>) op
or alternatively CFBridgingRetain(op)
is used to hand an NSObject
over to CF-land while giving it a +1 retain count. You should handle a CFTypeRef
you create this way the same as you would handle a result of CFStringCreateCopy()
. This could also be represented by CFRetain((__bridge CFType)op); CFTypeRef someTypeRef = (__bridge CFType)op;
__bridge
just casts between pointer-land and Objective-C object-land. If you have no inclination to use the conversions above, use this one.
Maybe this is helpful. Myself, I prefer the CFBridging…
macros quite a bit over the plain casts.
I found another explanation in the iOS documentation that I think is easier to understand:
__bridge
transfers a pointer between Objective-C and Core Foundation with no transfer of ownership.
__bridge_retained (CFBridgingRetain)
casts an Objective-C pointer to a Core Foundation pointer and also transfers ownership to you.
You are responsible for calling CFRelease or a related function to relinquish ownership of the object.
__bridge_transfer (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.
Source: Toll-Free Bridged Types
As a follow-on, in this specific case, if you are on iOS, Apple recommends using UIColor and its -CGColor
method to return the CGColorRef into the colors
NSArray. In the Transitioning to ARC Release Notes, under the section "The Compiler Handles CF Objects Returned From Cocoa Methods", it is indicated that using a method like -CGColor
which returns a Core Foundation object will automatically be handled properly by the compiler.
Thus, they suggest using code like the following:
CAGradientLayer *gradientLayer = (CAGradientLayer *)[self layer];
gradientLayer.colors = [NSArray arrayWithObjects:(id)[[UIColor darkGrayColor] CGColor],
(id)[[UIColor lightGrayColor] CGColor], nil];
Note that as of right now, Apple's example code is missing the (id) cast I have above, which is still necessary to avoid a compiler error.
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