ARC和桥接投

使用ARC,我不能再将CGColorRefid 。 我了解到,我需要做一个桥梁演员。 按照clang文档 :

桥接的演员阵容是一个C风格演员,用三个关键字之一进行注释:

(__bridge T) op将操作数转换为目标typesT 如果T是可保留的对象指针types,则op必须具有不可保留的指针types。 如果T是一个不可保留的指针types,那么op必须有一个可保留的对象指针types。 否则,演员阵容不健全。 没有所有权转让,并且ARC不插入保留操作。

(__bridge_retained T) op将必须具有可保留对象指针types的操作数强制转换为目标types,该目标types必须是不可保留的指针types。 ARC会保留这个值,但是必须遵守本地值的通常优化,接收者负责平衡+1。

(__bridge_transfer T) op将必须具有不可保留的指针types的操作数强制转换为目标types,该types必须是可保留的对象指针types。 ARC将在封闭的完整expression式的末尾释放该值,受当地值的通常优化。

这些转换是为了传送对象进出ARC控制所必需的; 请参阅保留对象指针转换一节中的基本原理。

使用纯粹的__bridge_retained__bridge_transfer为分别发出不平衡的保留或释放,是不好的forms。

我会在哪种情况下使用?

例如, CAGradientLayer有一个colors属性,它接受一个CGColorRef数组。 我的猜测是我应该在这里使用__brige ,但是为什么我应该(或者不应该)不清楚。

我同意这个描述是混乱的。 由于我刚抓住他们,我会尽量总结一下:

  • (__bridge_transfer <NSType>) op或者CFBridgingRelease(op)用于在将CFTypeRef传递给ARC时消耗CFTypeRef的保留计数。 这也可以通过id someObj = (__bridge <NSType>) op; CFRelease(op); id someObj = (__bridge <NSType>) op; CFRelease(op);

  • (__bridge_retained <CFType>) op或者CFBridgingRetain(op)用于将NSObject交给CF-land,同时给它一个+1保留计数。 你应该像处理CFStringCreateCopy()的结果一样处理你创build的CFStringCreateCopy() 。 这也可以用CFRetain((__bridge CFType)op); CFTypeRef someTypeRef = (__bridge CFType)op; CFRetain((__bridge CFType)op); CFTypeRef someTypeRef = (__bridge CFType)op;

  • __bridge只是在指针地和Objective-C对象地之间进行投射。 如果您不想使用上述转换,请使用此转换。

也许这是有帮助的。 我自己,我更喜欢CFBridging…macros在比较简单的演员。

我在iOS文档中发现了另一个我认为更容易理解的解释:

  • __bridge在Objective-C和Core Foundation之间传递一个指针,但不转让所有权。

  • __bridge_retained (CFBridgingRetain)将一个Objective-C指针转换为Core Foundation指针,并将所有权转移给您。

    您有责任调用CFRelease或相关函数来放弃对象的所有权。

  • __bridge_transfer (CFBridgingRelease)将一个非Objective-C指针移动到Objective-C,并将所有权转移给ARC。

    ARC负责放弃对象的所有权。

来源: 免费桥接types

作为一个后续,在这个特定的情况下,如果你在iOS上,Applebuild议使用UIColor和-CGColor方法将CGColorRef返回到colors NSArray。 在“ 过渡到ARC发行说明 ”中的“编译器处理从cocoa方法返回的CF对象”一节中,指出使用-CGColor (返回Core Foundation对象)的方法将自动由编译器正确处理。

因此,他们build议使用如下代码:

 CAGradientLayer *gradientLayer = (CAGradientLayer *)[self layer]; gradientLayer.colors = [NSArray arrayWithObjects:(id)[[UIColor darkGrayColor] CGColor], (id)[[UIColor lightGrayColor] CGColor], nil]; 

请注意,截至目前,苹果的示例代码缺less(id)强制转换我上面,这仍然是必要的,以避免编译器错误。