首页 文章

ARC和桥接演员

提问于
浏览
161

使用ARC,我无法再将 CGColorRef 转换为 id . 我了解到我需要做一个桥接演员 . 根据clang docs

桥接强制转换是使用以下三个关键字之一注释的C样式强制转换:(__ bridge T)op将操作数强制转换为目标类型T.如果T是可保留对象指针类型,则op必须具有不可保留的指针类型 . 如果T是不可保留的指针类型,则op必须具有可保留的对象指针类型 . 否则演员阵容不合理 . 没有所有权转让,ARC不会保留任何保留操作 . (bridge_retained T)op将操作数(必须具有可保留的对象指针类型)强制转换为目标类型,该目标类型必须是不可保留的指针类型 . ARC保留该值,取决于对本地值的通常优化,并且接收方负责 balancer 1.( bridge_transfer T)op将必须具有不可保留指针类型的操作数强制转换为目标类型,该类型必须是可保留的对象指针类型 . ARC将在封闭的完整表达式的末尾释放值,这取决于对本地值的通常优化 . 为了将对象传入和传出ARC控制,需要这些演员表;请参阅有关可保留对象指针转换一节的基本原理 . 纯粹使用__bridge_retained或__bridge_transfer强制转换来说服ARC分别发出不 balancer 的保留或释放,这种形式很糟糕 .

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

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

3 回答

  • 32

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

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

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

    You are responsible 用于调用CFRelease或相关函数来放弃对象的所有权 .

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

    ARC is responsible 用于放弃对象的所有权 .

    资料来源:Toll-Free Bridged Types

  • 52

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

    • (__bridge_transfer <NSType>) op 或者 CFBridgingRelease(op) 用于在将其传输到ARC时使用 CFTypeRef 的保留计数 . 这也可以用 id someObj = (__bridge <NSType>) op; CFRelease(op); 表示

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

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

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

  • 212

    作为后续,在这种特定情况下,如果您在iOS上,Apple建议使用UIColor及其 -CGColor 方法将CGColorRef返回到 colors NSArray . 在Transitioning to ARC Release Notes中,在"The Compiler Handles CF Objects Returned From Cocoa Methods"部分下,表明使用返回Core Foundation对象的类似 -CGColor 的方法将由编译器自动正确处理 .

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

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

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

相关问题