1.toll-free bridged
Core Foundation和Foundation框架的一些数据类型是可以相互转换的。这些可以相互转换的数据类型称为toll-free bridged
数据类型。下表列出了可以相互转换的类型:
2.转换语义和生命周期语义
编译器了解返回Core Foundation类型的Objective-C方法并遵循历史的命名规则。例如编译器知道UIColor
的CGColor
方法返回的CGColorRef
对象是不被持有的。
编译器并不自动管理Core Foundation对象的生命周期,通过使用Objective-C的转换方法或者Core Foundation的宏来告诉编译器Core Foundation对象的所有权语义。
-
__bridge
:转移Objective-C和Core Foundation之间的指针,没有所有权的转移 -
__bridge_retained
或CFBridgingRetain
:将一个Objective-C指针转换为一个Core Foundation指针,并且将所有权转移给开发者 -
__bridge_transfer
或CFBridgingRelease
:将一个非Objective-C指针转换为一个Objective-C指针,并且将所有权转交给ARC
下面的例子展示了上面部分关键字和宏的使用:
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
下面的例子展示了Core Foundation内存管理函数的使用,
- (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.
}
3.参考文献
提升代码质量最神圣的三部曲:模块设计(谋定而后动) -->无错编码(知止而有得) -->开发自测(防患于未然)