ARC和桥接投
使用ARC,我不能再将CGColorRef
为id
。 我了解到,我需要做一个桥梁演员。 按照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)强制转换我上面,这仍然是必要的,以避免编译器错误。