让我们考虑简单的X类:
@implementation X
/* primary convenience initializer */
- (id)init {
NSLog(@"init: self=%@", self);
return [self initWithValue:0];
}
/* secondary convenience initializer */
- (id)initWithValue:(int)val {
NSLog(@"initWithValue: self=%@", self);
return [self initWithValue:val andText:@""];
}
/* designated initializer */
- (id)initWithValue:(int)val andText:(NSString*)text {
self = [super init];
if (self) {
// some initial stuff
}
NSLog(@"initWithValue: andText: self=%@", self);
return self;
}
@end
然后实例化一个类X:
X *x = [[X alloc] init];
日志结果如下:
init: self=<X: 0x8f25050>
initWithValue: self=<X: 0x8f25050>
initWithValue: andText: self=<X: 0x8f25050>
当然不足为奇。所有初始化程序中的实例地址都相同。但我的问题是:出于什么原因我应该在指定的初始化程序中插入自检?
if (self) {
// some initial stuff
}
由于此时自已存在。而且,之前的一行是调用超级初始化器:
self = [super init];
这是什么意思? 自我地址可能会改变吗?任何提示?
恕我直言,使用自己的地址代表或出于任何其他目的,如果自我可能在初始化者中发生变化,可能会导致奇怪的问题。
答案 0 :(得分:0)
您需要检查的原因是您不知道您的超类中发生了什么。当你打电话
self = [super init];
你的超级班级可以正确地初始化你的对象,或者如果发生了什么事情可以返回&#34; nil&#34;。如果它返回nil,当然你不想继续对nil指针进行任何进一步的初始化。这就是你检查的原因。
self = [super init];
if (self){
//my further initialisation only if my super class didn't return nil
}
return self; //which is nil if my superclass failed the initialisation
答案 1 :(得分:0)
alloc
方法只为您的类实例分配内存。在alloc
之后,您有一个指向内存的指针(例如,0x8f25050
),已为您的实例分配。但它尚未初始化。它没有任何价值。因此,您必须调用init
方法,并检查您的实例是否为零。
答案 2 :(得分:0)
初始化导致初始化创建的对象。请参阅Object Initialization以了解初始化的必要性。在阅读本文档之前,只需了解Object Allocation alone(不是初始化)
在这一行self = [super init];
中,您创建的对象的超类属性将被初始化。
回答第一个问题:for what reason should I insert self checking in the designated initializer?
有些人可能会使用new
评论创建对象。然后分别调用initilization,在它们之间,由于引用计数原因,它们可能会释放对象,请查看self
。