Toll-Free Bridged Types
There are a number of data types in the Core Foundation framework and the Foundation framework that can be used interchangeably. Data types that can be used interchangeably are also referred to as toll-free bridged data types. This means that you can use the same data structure as the argument to a Core Foundation function call or as the receiver of an Objective-C message invocation. For example, NSLocale
(see NSLocale Class Reference) is interchangeable with its Core Foundation counterpart, CFLocale (see CFLocale Reference).
Not all data types are toll-free bridged, even though their names might suggest that they are. For example, NSRunLoop
is not toll-free bridged to CFRunLoop, NSBundle
is not toll-free bridged to CFBundle, and NSDateFormatter
is not toll-free bridged to CFDateFormatter. Table 1 provides a list of the data types that support toll-free bridging.
Casting and Object Lifetime Semantics
Through toll-free bridging, in a method where you see for example an NSLocale *
parameter, you can pass a CFLocaleRef
, and in a function where you see a CFLocaleRef
parameter, you can pass an NSLocale
instance. You also have to provide other information for the compiler: first, you have to cast one type to the other; in addition, you may have to indicate the object lifetime semantics.
The compiler understands Objective-C methods that return Core Foundation types and follow the historical Cocoa naming conventions (see Advanced Memory Management Programming Guide). For example, the compiler knows that, in iOS, the CGColor returned by the CGColor
method of UIColor
is not owned. You must still use an appropriate type cast, as illustrated by this example:
NSMutableArray *colors = [NSMutableArray arrayWithObject:(id)[[UIColor darkGrayColor] CGColor]]; |
[colors addObject:(id)[[UIColor lightGrayColor] CGColor]]; |
The compiler does not automatically manage the lifetimes of Core Foundation objects. You tell the compiler about the ownership semantics of objects using either a cast (defined in objc/runtime.h
) or a Core Foundation-style macro (defined in NSObject.h
):
__bridge
transfers a pointer between Objective-C and Core Foundation with no transfer of ownership.__bridge_retained
orCFBridgingRetain
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
orCFBridgingRelease
moves a non-Objective-C pointer to Objective-C and also transfers ownership to ARC.ARC is responsible for relinquishing ownership of the object.
Some of these are shown in the following example:
NSLocale *gbNSLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_GB"]; |
CFLocaleRef gbCFLocale = (__bridge CFLocaleRef)gbNSLocale; |
CFStringRef cfIdentifier = CFLocaleGetIdentifier(gbCFLocale); |
NSLog(@"cfIdentifier: %@", (__bridge NSString *)cfIdentifier); |
// Logs: "cfIdentifier: en_GB" |
CFLocaleRef myCFLocale = CFLocaleCopyCurrent(); |
NSLocale *myNSLocale = (NSLocale *)CFBridgingRelease(myCFLocale); |
NSString *nsIdentifier = [myNSLocale localeIdentifier]; |
CFShow((CFStringRef)[@"nsIdentifier: " stringByAppendingString:nsIdentifier]); |
// Logs identifier for current locale |
The next example shows the use of Core Foundation memory management functions where dictated by the Core Foundation memory management rules:
- (void)drawRect:(CGRect)rect { |
CGContextRef ctx = UIGraphicsGetCurrentContext(); |
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); |
CGFloat locations[2] = {0.0, 1.0}; |
NSMutableArray *colors = [NSMutableArray arrayWithObject:(id)[[UIColor darkGrayColor] CGColor]]; |
[colors addObject:(id)[[UIColor lightGrayColor] CGColor]]; |
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)colors, locations); |
CGColorSpaceRelease(colorSpace); // Release owned Core Foundation object. |
CGPoint startPoint = CGPointMake(0.0, 0.0); |
CGPoint endPoint = CGPointMake(CGRectGetMaxX(self.bounds), CGRectGetMaxY(self.bounds)); |
CGContextDrawLinearGradient(ctx, gradient, startPoint, endPoint, |
kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation); |
CGGradientRelease(gradient); // Release owned Core Foundation object. |
} |
Toll-Free Bridged Types
Table 1 provides a list of the data types that are interchangeable between Core Foundation and Foundation. For each pair, the table also lists the version of OS X in which toll-free bridging between them became available.
Copyright © 2003, 2013 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2013-12-16