ARC不兼容的类型铸造

时间:2014-12-04 20:30:31

标签: cocoa automatic-ref-counting foundation

我正在使用我从Apple有用的UIElementUtilities应用程序中借用的Core Foundations方法。问题是我希望更新这个借用的方法,以便它在Apple的新自动引用计数(ARC)系统下运行。通过在变量之前插入'__bridge'限定符,我已经取得了一些进展以适应大多数借用的方法,但是使用下面显示的方法,我在尝试转换为ARC后得到以下错误:“错误:不兼容的类型转换'NSString __strong *'使用__bridge强制转换为“CFTypeRef *”(又名“const void **”)。如何制作一个可接受的指向'actionDescription'缓冲区的指针,以便将其内容重新转换为NSString?

+ (NSString *)descriptionOfAction:(NSString *)actionName ofUIElement:(AXUIElementRef)element {

NSString * actionDescription = nil;

AXUIElementCopyActionDescription(element, (__bridge CFStringRef)actionName, (__bridge CFStringRef *)&actionDescription);

return actionDescription;

//return [actionDescription autorelease];

}

1 个答案:

答案 0 :(得分:2)

有趣的问题。

在ARC中,当您为变量分配引用时,ARC需要知道如何处理变量的先前值。如果变量是__strong,则需要释放旧引用,如果它是__unsafe_unretained,它只能丢弃旧引用,等等。所有这些都发生在大多数情况下,而不需要担心。

当您将指针传递给包含引用的变量时,它会变得有点复杂,ARC需要知道指向变量的限定符。 Objective-C使用一种称为 pass-by-writeback 的技术,它可以涉及使用隐藏的临时变量来确保它们都能正常工作,有关详细信息,请参阅Objective-C Automatic Reference Counting。 Core Foundation没有相应的功能,这就是你的转换绊倒。

解决方案是将函数传递给指向Core Foundation类型变量的指针,然后在调用后传递给Objective-C和ARC:

+ (NSString *)descriptionOfAction:(NSString *)actionName ofUIElement:(AXUIElementRef)element
{   
   CFStringRef actionDescription = nil;

   AXUIElementCopyActionDescription(element, (__bridge CFStringRef)actionName, &actionDescription);

   return (__bridge_transfer NSString *)actionDescription;
}

注意使用__bridge_transfer - 函数名称中的Copy表示返回的CFStringRef归调用者所有,必须在使用后释放__bridge_transfer将所有权交给ARC,然后负责发布参考资料。

HTH