Init方法:这两者有什么区别?

时间:2013-01-09 00:29:28

标签: objective-c initialization init

我目前正在阅读Apple的“Objective with 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;

}

VS

- (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 个答案:

答案 0 :(得分:3)

第二个是圆形的,将导致无限递归。

修改

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

答案 1 :(得分: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要指明,代码的编写者可能会发现有点hacky来编写nil willy nilly。因此,这是一种方便的方法,您不会传递dateOfBirth,只传递名字和姓氏,而是仅使用nil dateOfBirth来调用另一种方法。它只是让代码编写者在撰写nil时不会感到害怕的一种方式。

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

答案 2 :(得分:0)

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

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

但是,在第二种情况下,init邮件会发送到self,这就是您要拨打的init。这意味着init会一直调用自己直到你崩溃。

看起来您假设aFirstNameaLastName分配了一些神奇的方式,但您必须教会您的对象如何执行此操作并在此init方法中自行实现

答案 3 :(得分:0)

这是手册中的内容:

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

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

编辑

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