使用指定的初始化程序和多个初始值设定项时会产生疑问

时间:2014-01-24 11:44:33

标签: ios

让我们考虑简单的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];

这是什么意思? 自我地址可能会改变吗?任何提示?

恕我直言,使用自己的地址代表或出于任何其他目的,如果自我可能在初始化者中发生变化,可能会导致奇怪的问题。

3 个答案:

答案 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