5

在过去,我们被训练编写这样的 init 方法:

富.h:

-(id) initWithInteger: (NSInteger) someNumber;

Foo.m:

-(id) initWithInteger: (NSInteger) someNumber {
    if ((self = [super init])) { 
       doSomeStuff;
    }
    return self;
 }

但是那些身份转换现在是禁止的。那么这些方法现在应该怎么看呢?

编辑:这是一个图书馆。所以没有人知道调用代码可能是什么样子。

4

3 回答 3

8

为什么说退货id是禁忌?ARC规范

init方法必须是实例方法并且必须返回一个 Objective-C 指针类型。此外,如果程序声明或包含对 init 方法的调用,该方法的返回类型既不是 id 也不是指向声明类的超类或子类的指针(如果该方法在类上声明) 或调用的静态接收器类型(如果它是在协议上声明的)。

此外,请记住,使用ARC是针对每个文件的决定,即使用 ARC 编译的代码可以与没有 ARC 的代码一起使用,反之亦然。对于库的头文件,您应该准备它以便可以在两者上使用它,但为非 ARC 情况准备它就足够了。

于 2011-07-29T14:31:27.157 回答
4

这是我现在要做的:

-(id) initWithInteger: (NSInteger) someNumber {
    self = [super init];
    if (self) { 
       doSomeStuff;
    }
    return self;
}

它使警告消失了,并且在逻辑上是等效的,尽管没有那么优雅。

呃,我现在觉得自己像个傻瓜,没有阅读问题来理解它。但我发现这个链接指向可能有帮助的东西。具体来说,它在第 5 节中指出:

init 方法必须是实例方法并且必须返回一个 Objective-C 指针类型。此外,如果程序声明或包含对 init 方法的调用,该方法的返回类型既不是 id 也不是指向声明类的超类或子类的指针(如果该方法在类上声明) 或调用的静态接收器类型(如果它是在协议上声明的)。

基于此,看起来你不需要做任何事情,这是有道理的。即使是苹果公司也没有对它的开发者那么残忍。您是否收到编译器错误?我还没有跳到 Lion,所以 ARC 还没有出现在我的雷达上。

于 2011-07-29T12:59:33.893 回答
0

在过去,我们被训练编写这样的 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)仅作为强制转换表达式的语法无效,因为强制转换本身是无效的。

在强制转换表达式中添加一个桥关键字可以满足编译器的要求,因为你告诉它你想要它做什么(没有桥关键字的跨桥强制转换是无效的,因为编译器必须猜测你的意思,它会拒绝),但在类型声明中是无效的,因为这不是模棱两可的。过桥发生在强制转换表达式(当有一个时),而不是在参数通道或返回。

于 2012-12-23T07:02:21.860 回答