OC中的Toll-Free Bridging(桥接)机制

本人有若干成套学习视频, 可试看! 可试看! 可试看, 重要的事情说三遍 包含Java, 数据结构与算法, iOS, 安卓, python, flutter等等, 如有需要, 联系微信tsaievan.

在开发中, 我们除了要涉及OC对象, 还要涉及Core Foundation类型的对象

  • Core Foundation框架中的对象CFArrayRef,CFMutableDictionaryRef

  • 采用Core Foundation框架惯例的其他框架Core Graphics中的CGColorSpaceRef,CGGradientRef

编译器不会自动挂历CF对象的生命周期, 所以必须调用CFRetain,CFRelease之类的函数来管理CF对象

如果要实现OC和CF对象之间的互相转换, 有几个关键字可以使用

  • __bridge可以将OC对象转成CF对象,但不会变更所有权
  • __bridge_retained或者CFBridgingRetain可以将OC指针转换为CF指针, 同时变更所有权
  • __bridge_transfer或者CFBridgingRelease可以将非OC指针转换成OC指针, 同时变更所有权给ARC. ARC负责释放对象

例如你有如下代码:

- (void)logFirstNameOfPerson:(ABRecordRef)person {
 
    NSString *name = (NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
    NSLog(@"Person's first name: %@", name);
    [name release];
}

你需要替换为:

- (void)logFirstNameOfPerson:(ABRecordRef)person {
 
    NSString *name = (NSString *)CFBridgingRelease(ABRecordCopyValue(person, kABPersonFirstNameProperty));
    NSLog(@"Person's first name: %@", name);
}
编译器处理OC方法返回的CF对象

编译器知道OC方法返回CF对象是遵守OC命名规则的, 例如, 在iOS中, UIColor方法返回CGColor对象是不被持有的,但还是需要强转, 不过不需要使用__bridge等关键字

NSMutableArray *colors = [NSMutableArray arrayWithObject:(id)[[UIColor darkGrayColor] CGColor]];
[colors addObject:(id)[[UIColor lightGrayColor] CGColor]];
使用所有权关键字转换函数参数

调用函数或者方法的时候, 函数或者方法的参数类型是指定的, 这个时候就需要强转了.

NSArray *colors = <#An array of colors#>;
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)colors, locations);

当所有权没有发生变更时, CF对象还是需要手动调用CFRelease之类的方法释放

- (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.
}

PS. 本人有若干成套学习视频, 包含Java, 数据结构与算法, iOS, 安卓, python, flutter等等, 如有需要, 联系微信tsaievan.

你可能感兴趣的:(OC中的Toll-Free Bridging(桥接)机制)