2011-05-19 199 views

回答

1

有必要确保正确初始化来自超类MyObject的继承实例变量。

2

由于Objective-C是面向对象的,因此您可以继承其他类。当你从其他类继承时,你可以拦截消息并决定是否将它们传递给你继承的类。在初始化的情况下,它几乎是总是重要的是要做self = [super init]或使用该类的指定init方法来确保正确创建对象。想象一下,如果在你的init方法的MyObject中创建了你的类使用的NSMutableArray,但是init从未被调用,因为其他人从你的类继承而来,并且从来没有调用[super init]。然后,您将在每个您尝试使用NSMutableArray的地方都有无参考文件或不正确的指针。设置self等于[super init]的原因是自我可能改变的值,例如在错误恢复中。

//this is valid 
-(id)init 
{ 
    if((self = [super init])) 
    { 
     if(someInitializationFails) 
     { 
      [self release]; 
      self = nil; 
     } 
    } 
    return self; 
} 
+0

您需要条件... – bbum 2011-05-19 21:26:00

+0

您指的是我忽略了'if((self = [super init])')的必要性吗?它看起来像海报了解条件,但我可以编辑。 – Joe 2011-05-19 21:34:45

+1

是的 - 有人会不经意地复制副本... – bbum 2011-05-19 21:58:17

1

威尔·希普利建议this(2009年):

- (id)init; 
{ 
if (!(self = [super init])) 
    return nil; 

// other stuff 
return self; 
} 

但为什么分配超级init的回归自我?

马特·加拉格尔的article试图解释它...

- 报价:

如果你还记得在一开始,我 说,initWithString:中 一个典型的[部分MyClass的页头] initWithString:@ “someString”] 调用转换成一个 objc_msgSend呼叫:

MyClass *myObject2 = objc_msgSend(myObject1, initSelector, @"someString"); 

因此,当我们得到 到方法的内部,自我 已经有一个值;其值为 myObject1(即,从[MyClass alloc] 调用返回的分配对象 。因为 没有它,超级调用 是不可能的,这是必不可少的 - 自我价值 使用编译器来发送 调用:

[super init]; 

变为:

objc_msgSendSuper(self, @selector(init)); 

是的,self已有 在初始化程序 开始时有一个值。实际上,它几乎是 保证是正确的,最终 的值。

- 引文结束

从本质上讲,我想很多人都感到困惑,以什么每个init方法的“自我”是指向准确,向上通过超链。

回答这个谜语是隐含在苹果的Objective-C Programming Language doc,下标题为指定初始化:

注意,初始化的B版发送 消息自行调用 initWithName:方法。因此,当接收者是B 类的实例时,它调用B版本 initWithName :,并且当接收者 是C类的实例时,它调用C版本。

或换句话说,'self'变量指向正在初始化的实例。再次强调,通过超类链的所有这些init方法都由我们的实例继承,因此,它们中的'self'变量指向我们的实例(除非明确更改)。

我对不对?当然!