覆盖init

时间:2012-11-01 00:13:44

标签: objective-c

  

可能重复:
  In Objective-C why should I check if self = [super init] is not nil?

我是Ob-C的新手,我很难理解为什么返回的值是非零的,如“if语句”所测试的那样。

- (id)init
{
    self = [super init];
    if (self) {
        // Initialization code here.
    }

    return self;
}

此方法首先调用父初始值设定项。执行父级的初始值设定项可确保正确初始化任何继承的实例变量。 您必须将执行父级init方法的结果分配给self,因为初始化程序有权更改对象在内存中的位置(意味着它的引用将更改)。 如果父级的初始化成功,则返回的值将为非零,由if语句测试。正如注释所示,在随后的块中,您可以为对象放置自己的自定义初始化代码。这通常涉及分配和初始化类中的实例变量。

粘贴代码和文本 来自Stephen Kochan“Objective-C编程,第四版”

1 个答案:

答案 0 :(得分:2)

考虑以下情况,您有一个父类,我们称之为Parent,它具有以下布局:

@implementation Parent {
    int value;
}

您有一个Child类,它是Parent的子类,并具有以下布局:

@implementation Child {
    int other;
}

Child子类中,您无法直接访问名为Parent的{​​{1}} ivar。但是,在初始化时,value会将一些整数分配给Parent,而value中的某些功能取决于所设置的值。

如果Parent未致电Child,则[super init]永远不会被初始化,而value继承的Parent的部分功能将被破坏。定义Child方法以返回指向初始化对象实例的指针。如果忽略init的返回值,则可能会遇到麻烦,因为父init可能已决定将对象实例重新分配给除分配器提供的位置之外的某个位置。

例如,NSString can detect initialization with empty string literals,并将返回指向常量NSString引用的指针,而不是堆上的引用。所以说你只需要调用[super init]并忽略其返回值,并继续使用传递给[super init] self方法的Child指针值,你就会突然使用悬空指针!

这是一个极端的情况,但重点是,如果您打算从父类继承功能,则应将self分配给init,并且应该检查它是否返回[super init],因为它可能已决定初始化失败并破坏分配器提供给它的内存。