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

时间:2013-08-05 20:27:49

标签: ios objective-c cocoa-touch core-graphics 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);

但会:

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

  CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)CFBridgingRetain(colors), locations);

是一个更好的解决方案吗?

2 个答案:

答案 0 :(得分:22)

您并非“拥有”Core Foundation对象startColorendColor,因为它们是 不是由名称中包含“Create”或“Copy”的函数返回的(比较“Core Foundation Programming Guide for Core Foundation”中的"The Create Rule"。 而且由于您不拥有这些对象,因此您不得将“所有权”转移到ARC CFBridgingRelease()。所以

[NSArray arrayWithObjects:(__bridge id)startColor, (__bridge id)endColor, nil];

是对的。并且

CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)colors, locations);

也是正确的,因为

CGGradientCreateWithColors(colorSpace, (CFArrayRef)CFBridgingRetain(colors), locations);

会将(+1)保留的数组传递给CGGradientCreateWithColors()。这将是一个记忆 泄漏,因为该函数不释放colors参数。

答案 1 :(得分:0)

使用NSURL是同样的问题

NSString *soundPath = [[NSBundle mainBundle] pathForResource:@"sound" ofType:@"wav"];
NSURL *soundURL = [NSURL fileURLWithPath:soundPath];
AudioServicesCreateSystemSoundID(CFBridgingRetain(soundURL), &soundEffect);