ARC和桥接演员

Mor*_*ess 165 objective-c type-conversion clang automatic-ref-counting

有了ARC,我不能再投CGColorRefid.我了解到我需要做一个桥接演员.据clang docs说:

一个桥接投是C样式转换标注有三个关键字之一:

(__bridge T) op将操作数强制转换为目标类型T.如果T 是可保留对象指针类型,则op必须具有不可保留的指针类型.如果T是不可保留的指针类型,则op必须具有可保留的对象指针类型.否则演员阵容不合理.没有所有权转让,ARC不会保留任何保留操作.

(__bridge_retained T) op将必须具有可保留对象指针类型的操作数强制转换为目标类型,该目标类型必须是不可保留的指针类型.ARC保留该值,取决于对本地值的通常优化,并且接收方负责平衡+1.

(__bridge_transfer T) op将操作数(必须具有不可保留的指针类型)强制转换为目标类型,该目标类型必须是可保留的对象指针类型.ARC将在封闭的完整表达式的末尾释放值,这取决于对本地值的通常优化.

为了将对象传入和传出ARC控制,需要这些演员表; 请参阅有关可保留对象指针转换一节的基本原理.

纯粹使用__bridge_retained__bridge_transfer铸造来说服ARC分别发出不平衡的保留或释放,这种形式很差.

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

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

mon*_*dom 215

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

  • (__bridge_transfer <NSType>) op或者CFBridgingRelease(op)用于消耗保留计数,CFTypeRef同时将其转移到ARC.这也可以用来表示id someObj = (__bridge <NSType>) op; CFRelease(op);

  • (__bridge_retained <CFType>) op或者CFBridgingRetain(op)用来交给NSObjectCF-land,同时给它+1保留计数.你应该处理一个CFTypeRef你创建这种方式的方法,就像处理结果一样CFStringCreateCopy().这也可以用来表示CFRetain((__bridge CFType)op); CFTypeRef someTypeRef = (__bridge CFType)op;

  • __bridge只是在指针 - 土地和Objective-C对象 - 土地之间施放.如果您不想使用上述转换,请使用此转换.

也许这很有帮助.我自己,我CFBridging…比普通的演员更喜欢宏.

  • 是的,如果你只是在弧形地带强/弱就足够了,但是当你在弧形和非弧形环境之间转换物体时,你仍然需要考虑引擎盖下的保留计数含义 (4认同)
  • 并不是的.你需要考虑进出ARC土地.这对于抓住自动释放非常有用.(有趣的是:ARC修复了一个常见的模式,比如从字典中获取对象,然后在使用它之前将其删除,等等) (3认同)
  • 使用分析器工具(shift + command + B)可以帮助解决这种疑问,因为如果当前代码泄漏内存,它会以自然语言告诉你.如果是这样,你可能会使用挡泥板,而你应该使用非挡板.如果分析器没有警告您代码行中的任何内容,那么您可能正在使用当前代码 (3认同)
  • 一旦进入ARC土地,你就不再考虑保留计数了,只考虑强弱参考. (2认同)

gre*_*lom 54

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

  • __bridge 在Objective-C和Core Foundation之间传输指针而不转移所有权.

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

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

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

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

资料来源:免费桥接类型


Bra*_*son 32

作为后续,在这种特定情况下,如果您使用的是iOS,Apple建议使用UIColor及其-CGColor方法将CGColorRef返回到colorsNSArray中.在转换到ARC发行说明中,在"编译器处理从Cocoa方法返回的CF对象"部分下,指示使用-CGColor返回Core Foundation对象的方法将由编译器自动正确处理.

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

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

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

  • @JoeyHagedorn - 也许你在我的答案的第一句中错过了我对ARC文档的引用,但这不仅仅是在ARC下有效,它是从这些UIColor转换器方法向NSArrays提供CGColorRef引用的推荐方法.我和许多其他人在启用ARC的应用程序中使用此确切代码.从返回Core Foundation对象的方法立即转换为(id)会自动将该对象正确地桥接到ARC. (11认同)