169

使用 ARC,我无法再CGColorRef转换为id. 我了解到我需要进行桥接演员表。根据clang 文档

桥接强制转换是使用以下三个关键字之一注释的 C 样式强制转换:

(__bridge T) op将操作数强制转换为目标类型T。如果T 是可保留对象指针类型,则op必须具有不可保留指针类型。如果T是不可保留的指针类型,则 op 必须具有可保留的对象指针类型。否则,演员阵容不正确。没有所有权转移,ARC 没有插入保留操作。

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

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

需要这些转换才能将对象移入和移出 ARC 控制;请参阅关于可保留对象指针的转换部分的基本原理。

纯粹使用__bridge_retainedor__bridge_transfer强制转换来说服 ARC 分别发出不平衡的保留或释放是不好的形式。

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

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

4

3 回答 3

217
于 2011-08-31T18:23:59.907 回答
57

I found another explanation in the iOS documentation that I think is easier to understand:

  • __bridge transfers a pointer between Objective-C and Core Foundation with no transfer of ownership.

  • __bridge_retained (CFBridgingRetain) casts an Objective-C pointer to a Core Foundation pointer and also transfers ownership to you.

    You are responsible for calling CFRelease or a related function to relinquish ownership of the object.

  • __bridge_transfer (CFBridgingRelease) moves a non-Objective-C pointer to Objective-C and also transfers ownership to ARC.

    ARC is responsible for relinquishing ownership of the object.

Source: Toll-Free Bridged Types

于 2013-10-29T17:02:09.333 回答
33

As a follow-on, in this specific case, if you are on iOS, Apple recommends using UIColor and its -CGColor method to return the CGColorRef into the colors NSArray. In the Transitioning to ARC Release Notes, under the section "The Compiler Handles CF Objects Returned From Cocoa Methods", it is indicated that using a method like -CGColor which returns a Core Foundation object will automatically be handled properly by the compiler.

Thus, they suggest using code like the following:

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

Note that as of right now, Apple's example code is missing the (id) cast I have above, which is still necessary to avoid a compiler error.

于 2011-10-18T03:28:57.463 回答