0

我目前正在阅读 Apple 的“使用 Objective C 编程”手册,它显示了这两个 init 方法。它们之间有什么区别,什么时候适合使用?

  - (id)initWithFirstName:(NSString *)aFirstName lastName:(NSString *)aLastName dateOfBirth: (NSDate *)aDateOfBirth {

    self = [super init];

    if (self) {
        _firstName = aFirstName;
        _lastName = aLastName;
        _dateOfBirth = aDateOfBirth;
    }

    return self;

}

对比

- (id)initWithFirstName:(NSString *)aFirstName lastName:(NSString *)aLastName {
    return [self initWithFirstName:aFirstName lastName:aLastName dateOfBirth:nil];
}

手册可以在这里找到http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html#//apple_ref/doc/uid/TP40011210-CH5-SW15

4

4 回答 4

3

第二个是循环的,将导致无限递归。

编辑:

对于更新后的问题,初始化程序的第二个版本只是为了方便,因为您不再需要指定第三个参数。

于 2013-01-09T00:32:39.910 回答
0

第一个是正常的自定义初始化,它正确设置您的参数并初始化您的类。

第二个调用自己,因此它将在无限递归中一次又一次地调用自己,最终导致堆栈溢出——应用程序将本质上冻结并崩溃。

苹果文档不建议......你可能误读了它


苹果文档仍然没有建议,但它很接近:

- (id)initWithFirstName:(NSString *)aFirstName lastName:(NSString *)aLastName {
return [self initWithFirstName:aFirstName lastName:aLastName dateOfBirth:nil]; // Not the same method, passes dateOfBirth parameter.
}

被调用的方法可能如下所示:

- (id)initWithFirstName:(NSString *)aFirstName lastName:(NSString *)aLastName dateOfBirth: (NSDate *)dateOfBirth {

   if (self = [super init]) {

         _firstName = aFirstName;
         _lastName = aLastName
         _dateOfBirth = dateOfBirth;
   }

        return self;

}

它调用另一个类似的方法,但传递了一个dateOfBirth参数,它不是同一个方法。


好的,所以区别很简单,如果调用任一方法的类不想dateOfBirth从类中传递参数,并且此 Person 实例没有dateOfBirth他希望指定的参数,代码编写者可能会觉得它有点 hackynil随便写。所以这是一个方便的方法,你不传递 a dateOfBirth,只传递名字和姓氏,它调用另一个方法简单地nilfor dateOfBirth。它只是让代码编写者在编写时不会感到害怕的一种方式nil

所以一切都在这两种方法中被初始化。

于 2013-01-09T00:37:52.600 回答
0

正如@ThomasW 指出的那样,第二种情况是错误的。在第一种情况下,您调用[super init]让您的类派生自初始化它们在您正在实例化的对象中的份额。

这是有效的,因为因为super指示init消息应该由知道该做什么的基类接收。请注意,它不知道如何记住您的名字或姓氏。

但是,在第二种情况下,init消息被发送到self,这就是init您呼叫的来源。这意味着init它将继续调用自身,直到您崩溃。

看起来你假设aFirstName并且aLastName以某种神奇的方式分配,但你必须教你的对象如何做到这一点,并在这个init方法中完全自己实现它。

于 2013-01-09T00:42:30.790 回答
0

这是手册中写的:

- (id)initWithFirstName:(NSString *)aFirstName lastName:(NSString *)aLastName {
    return [self initWithFirstName:aFirstName lastName:aLastName dateOfBirth:nil];
}

所以它不会导致无限循环,因为被调用的方法是另一个,它不是递归的。

编辑

第二种方法是在您不想使用 dateOfBirth 初始化对象时使用。实际上,如果您使用 initWithFirstName:lastName: ,此属性将为 nil。

于 2013-01-09T01:00:08.977 回答