ARC和桥接演员

时间:2011-08-12 06:24:26

标签: objective-c automatic-ref-counting type-conversion clang

使用ARC,我无法再将CGColorRef投射到id。我了解到我需要做一个桥接演员。根据{{​​3}}:

  

桥接演员是使用以下三个关键字之一注释的C风格演员:

     

(__bridge T) op将操作数强制转换为目标类型T。如果T   是一个可保留的对象指针类型,然后op必须有一个   不可保留的指针类型。如果T是不可保留的指针类型,   那么op必须有一个可保留的对象指针类型。否则演员   是不正确的。没有所有权转让,ARC插入没有   保留运营。

     

(__bridge_retained T) op强制转换必须具有的操作数   可保留对象指针类型,必须是目标类型   不可保留的指针类型。 ARC保留了价值,受制于   通常对本地值进行优化,并且收件人负责   为了平衡+1。

     

(__bridge_transfer T) op强制转换必须具有的操作数   不可保留的指针类型,到目标类型,必须是a   可保留的对象指针类型。 ARC将在最后发布该值   封闭的完整表达式,取决于通常的优化   关于当地价值观。

     

为了将对象传入和传出,需要这些强制转换   ARC控制;请参阅转换部分的基本原理   可保留的对象指针。

     

纯粹使用__bridge_retained__bridge_transfer演员来说服   ARC分别发出不平衡的保留或释放是不好的   形式。

我会在什么样的情况下使用它们?

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

3 个答案:

答案 0 :(得分:212)

我同意描述令人困惑。既然我抓住了它们,我会试着总结一下:

  • (__bridge_transfer <NSType>) opCFBridgingRelease(op)用于在将CFTypeRef转移到ARC时使用id someObj = (__bridge <NSType>) op; CFRelease(op);的保留计数。这也可以用(__bridge_retained <CFType>) op

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

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

也许这很有帮助。我自己,我更喜欢{{1}}宏而不是简单的演员。

答案 1 :(得分:53)

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

  • __bridge在Objective-C和Core Foundation之间转移指针,不转让所有权。

  • __bridge_retained (CFBridgingRetain) Core Foundation 指针投射 Objective-C 指针,并将所有权转让给您。

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

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

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

来源:Toll-Free Bridged Types

答案 2 :(得分:32)

作为后续操作,在这种特定情况下,如果您使用的是iOS,Apple建议使用UIColor及其-CGColor方法将CGColorRef返回到colors NSArray。在Transitioning to ARC Release Notes中的“编译器处理从Cocoa方法返回的CF对象”部分下,表明使用返回Core Foundation对象的-CGColor之类的方法将由编译器自动处理

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

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

请注意,截至目前,Apple的示例代码缺少上面的(id)演员,这对于避免编译错误仍然是必要的。