使用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
,但究竟为什么我应该(或不应该)不清楚。
答案 0 :(得分:212)
我同意描述令人困惑。既然我抓住了它们,我会试着总结一下:
(__bridge_transfer <NSType>) op
或CFBridgingRelease(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负责放弃对象的所有权。
答案 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)演员,这对于避免编译错误仍然是必要的。