在过去,我们被训练编写这样的 init 方法:
富.h:
-(id) initWithInteger: (NSInteger) someNumber;
Foo.m:
-(id) initWithInteger: (NSInteger) someNumber {
if ((self = [super init])) {
doSomeStuff;
}
return self;
}
但是那些身份转换现在是禁止的。那么这些方法现在应该怎么看呢?
那些不是演员表。在这种情况下,该简单的语法声明了方法的返回类型,因为(NSInteger)
后面的部分声明了该参数的类型。
声明方法的返回类型的语法在 ARC 下没有改变。您显示的代码将保持完全相同。
类型转换是表达式,因此 ARC 禁止的类型转换只能出现在表达式上下文中。例如,如果您说:
- (id) initWithCFThing:(CFThingRef)thing {
if ((self = [super init])) {
_thing = (NSThing *)thing; //Casts expression of type CFThingRef to object pointer type NSThing *; this is invalid
}
return self;
}
赋值表达式中的转换是无效的,因为它从 CF 对象转换为没有桥关键字的 Objective-C 对象指针(“可保留对象指针”)。反过来同样无效:
- (CFThingRef) CFThing {
return _thing; //Implicitly casts expression of object pointer type NSThing *to type CFThingRef; this is invalid
}
另一个方向也有同样的问题:给定return
语句的表达式将可保留对象指针强制转换为没有 bridge 关键字的 CF 对象类型。
注意错误在哪里。在每种情况下,错误都在一个表达式中:在 中initWithCFThing:
,它是赋值表达式中的显式转换表达式;在访问器CFThing
中,它是将语句中的表达式隐式return
转换为方法的返回类型。
在这两种情况下,就像您的情况一样,该方法的原型是完全有效的。当您为方法声明返回类型或参数类型时,无论有无 ARC,它仍然有效(CFThingRef)
。(id)
仅作为强制转换表达式的语法无效,因为强制转换本身是无效的。
在强制转换表达式中添加一个桥关键字可以满足编译器的要求,因为你告诉它你想要它做什么(没有桥关键字的跨桥强制转换是无效的,因为编译器必须猜测你的意思,它会拒绝),但在类型声明中是无效的,因为这不是模棱两可的。过桥发生在强制转换表达式(当有一个时),而不是在参数通道或返回。