ARC 和桥接铸件

使用 ARC,我不能再将 CGColorRef施放到 id。我学到了我需要做一个桥梁石膏。根据 叮当文件:

桥式石膏是一种 C 风格的演员阵容,用以下三个关键词中的一个进行注释:

(__bridge T) op将操作数强制转换为目标类型 T 是可保留的对象指针类型,则 op必须具有 不可保留的指针类型。如果 T是不可保留的指针类型, 则 op 必须具有可保留的对象指针类型 没有所有权转移,并且 ARC 插入 no 维持运作。

(__bridge_retained T) op强制转换操作数,操作数必须具有 可保留的对象指针类型,指向目标类型,该类型必须是 不可保留的指针类型。 ARC 保留该值,但受 通常对局部值进行优化,接收方负责 平衡那个 + 1。

(__bridge_transfer T) op强制转换操作数,操作数必须具有 不可保留的指针类型,指向目标类型,该类型必须是 可保留的对象指针类型。 ARC 将在最后释放该值 在通常的优化条件下,对封闭的完整表达式进行优化 地方价值观。

这些强制转换是为了传输进出对象 ARC 控件; 请参阅关于 可保持的对象指针。

纯粹使用 __bridge_retained__bridge_transfer转换来说服 ARC 发出的不平衡保留或释放,分别是差的 表格。

在什么样的情况下,我会使用每个?

例如,CAGradientLayer有一个 colors属性,它接受一个 CGColorRef数组。我的猜测是,我应该在这里使用 __brige,但确切的原因我应该(或不应该)不清楚。

86494 次浏览

我同意这个描述是令人困惑的,因为我刚刚掌握了它们,所以我试着总结一下:

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

  • (__bridge_retained <CFType>) op或者 CFBridgingRetain(op)也可以用来把 NSObject交给 CF-land,同时给它 + 1保留计数。您应该像处理 CFStringCreateCopy()的结果一样处理创建的 CFTypeRef。这也可以用 CFRetain((__bridge CFType)op); CFTypeRef someTypeRef = (__bridge CFType)op;来表示

  • __bridge只是在指针地和 Objective-C 对象地之间进行强制转换。如果您不想使用上面的转换,请使用这个转换。

也许这是有帮助的。我自己,我更喜欢相当多的 CFBridging…宏超过普通的强制转换。

作为后续,在这个特定的例子中,如果你在 iOS 上,Apple 建议使用 UIColor 及其 -CGColor方法将 CGColorRef 返回到 colors NSArray 中。在 过渡到 ARC 发布说明中,“编译器处理从 Cocoa 方法返回的 CF 对象”一节中指出,使用像 -CGColor这样返回 Core Foundation 对象的方法,编译器将自动正确处理。

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

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

注意,到目前为止,Apple 的示例代码没有使用上面的(id)强制转换,这对于避免编译器错误仍然是必要的。

我在 iOS 文档中找到了另一个我认为更容易理解的解释:

  • __bridge在 Objective-C 和 Core Foundation 之间传输一个指针,不进行所有权转移。

  • __bridge_retained (CFBridgingRetain)目标 C指针强制转换为 核心基金指针,并将所有权传递给您。

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

  • __bridge_transfer (CFBridgingRelease)移动一个 非目标 C指针 目标 C,并将所有权转移到 ARC。

    ARC 对放弃物品的所有权负有责任。

资料来源: 免费桥型