我目前正在阅读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];
}
找到
答案 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
会一直调用自己直到你崩溃。
看起来您假设aFirstName
和aLastName
分配了一些神奇的方式,但您必须教会您的对象如何执行此操作并在此init
方法中自行实现
答案 3 :(得分:0)
这是手册中的内容:
- (id)initWithFirstName:(NSString *)aFirstName lastName:(NSString *)aLastName {
return [self initWithFirstName:aFirstName lastName:aLastName dateOfBirth:nil];
}
所以它不会导致无限循环,因为被调用的方法是另一个,它不是递归的。
编辑
第二种方法是在您不想使用dateOfBirth初始化对象时使用。实际上,如果使用initWithFirstName:lastName :,则此属性将为nil。