你何时应该使用__bridge与CFBridgingRelease/CFBridgingRetain?

And*_*row 18 cocoa-touch core-graphics objective-c ios automatic-ref-counting

我有这个代码,使用"__bridge"来转换颜色的ID:

  CGColorRef tabColor = (5 == 5
                         ? [UIColor blueColor].CGColor
                         : [UIColor greenColor].CGColor);

  CGColorRef startColor = [UIColor whiteColor].CGColor;
  CGColorRef endColor   = tabColor;
  NSArray    *colors    = [NSArray arrayWithObjects:(__bridge id)startColor, (__bridge id)endColor, nil];

  CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)colors, locations);
Run Code Online (Sandbox Code Playgroud)

但会:

  NSArray    *colors    = [NSArray arrayWithObjects:(id)CFBridgingRelease(startColor), (id)CFBridgingRelease(endColor), nil];

  CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)CFBridgingRetain(colors), locations);
Run Code Online (Sandbox Code Playgroud)

是一个更好的解决方案

Mar*_*n R 22

您没有"拥有"Core Foundation对象startColor,endColor因为它们的名称中没有"Create"或"Copy"的函数返回它们(比较" Core Foundation内存管理编程指南"中的" 创建规则 ")因为你不拥有这些物品,所以你不能将所有权"转移"给ARC CFBridgingRelease().所以

[NSArray arrayWithObjects:(__bridge id)startColor, (__bridge id)endColor, nil];
Run Code Online (Sandbox Code Playgroud)

是正确的.和

CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)colors, locations);
Run Code Online (Sandbox Code Playgroud)

也是正确的,因为

CGGradientCreateWithColors(colorSpace, (CFArrayRef)CFBridgingRetain(colors), locations);
Run Code Online (Sandbox Code Playgroud)

会将(+1)保留的数组传递给CGGradientCreateWithColors().这将是内存泄漏,因为该函数不会释放colors参数.