正如我们所知,使用 ARC 我们需要一个 __bridge
来将 id 转换为 void *
:
void *t = (void *)self; // ERROR: Cast of ... requires a bridged cast
void *t = (__bridge void *)self; // CORRECT
C 函数调用也是如此:
void f(void *t) {
....
}
f((void *)self); // ERROR
f((__bridge void *)self); // CORRECT
我认为这也适用于方法,事实上这 Beginning ARC in iOS 5 Tutorial给出以下示例,并说明需要 __bridge
:
MyClass *myObject = [[MyClass alloc] init];
[UIView beginAnimations:nil context:(__bridge void *)myObject];
但是,今天我在我的一个程序的方法调用中不小心丢了一个 __bridge
,代码编译和运行没有任何问题。上面示例中的 __bridge
似乎是不必要的:
[UIView beginAnimations:nil context:(void *)myObject]; // COMPILED OK
这样对吗? __bridge
在这种情况下真的没有必要吗?或者删除它会改变代码的含义?
最佳答案
这包含在 ARC docs section 3.3.3 中(强调我的):
3.3.3 Conversion from retainable object pointer type in certain contexts
[beginning Apple 4.0, LLVM 3.1]
If an expression of retainable object pointer type is explicitly cast to a C retainable pointer type, the program is ill-formed as discussed above unless the result is immediately used:
- to initialize a parameter in an Objective-C message send where the parameter is not marked with the cf_consumed attribute, or to
- initialize a parameter in a direct call to an audited function where the parameter is not marked with the cf_consumed attribute.
在您的代码中,myObject
是一个“可保留对象指针”。 “C 可保留指针类型”包括 void*
(这是他们用作占位符的稍微草率的定义,因为 Core Foundation“对象”通常是 void*
) .
因此,如果用作方法参数,ObjC 对象可以隐式转换为 void*
。在那种情况下,没有额外的内存管理语义(即它等同于 __bridge
转换)。 Section 7.8警告我们 void*
将来可能不会被这样对待,但我不会担心。如果发生这种情况,添加 __bridge
将是微不足道的。
要记住的一件事是 myObject
在这里不 protected 。在动画完成之前,您需要确保以其他方式保留它,否则您可能会崩溃。
关于ios - __bridge 不需要方法参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21361643/