Toll-Free Bridging Types:关于桥接修饰符
2015-10-08 本文已影响380人
DerekMonster
Apple参考文档:参考文档
桥接
在开发中时常要使用Core Foundation框架,例如Core Graphics、Core Text等,有时需要在CF指针和OC对象之间进行转换,,在转换中需要注意内存管理。在ARC环境下,编译器不能自动管理CF对象的内存,我们需要使用CFRelease将其手动释放。因此需要时可以使用 __bridge
__bridge_transfer
__bridge_retained
进行桥接。
使用方法
-
__bridge
:CF和OC对象转化时只涉及对象类型不涉及对象所有权的转化
NSURL *url = [[NSURL alloc] initWithString:@"http://www.baidu.com"];
CFURLRef ref = (__bridge CFURLRef)url;
使用 __bridge
时,不管是从OC转换到CF还是从CF转换成OC,即内存的管理权(所有权)不随转换而转换,CF对象还是需要使用CFRelease(),OC对象由ARC自动管理。
-
__bridge_transfer
orCFBridgingRelease
:在CF指针转换成OC对象时,将CF指针的所有权交给ARC管理,此时ARC就能自动管理该内存
-
__bridge_retained
orCFBridgingRetain
:将OC对象转换成CF指针时,管理的所有交由使用者手动释放
NSURL *url = [[NSURL alloc] initWithString:@"http://www.baidu.com"];
CFURLRef ref = (__bridge_retained CFURLRef)url;
CFRelease(ref);
综合示例
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
- (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.
}