超级初始化对象

时间:2011-05-19 20:25:54

标签: objective-c memory-management super

  

可能重复:
  why does initializing subclasses require calling the super class's same init function?

我真的无法理解超级在初始化对象中的作用。 例如,有这个(例子 - 不是我写的)代码:

@implementation MyObject
  - (id) init
  {
     if([super init]){
       return self;
     } else {
       return nil;
     }
  }
  @end

[super init]实际上做了什么?我很困惑,不能明白这一点

3 个答案:

答案 0 :(得分:2)

由于Objective-C是面向对象的,因此您可以从其他类继承。当您从其他类继承时,您可以拦截消息并决定是否将它们传递给您继承的类。在init的情况下,执行self = [super init]几乎总是很重要,或者使用类的指定init方法来确保正确创建对象。想象一下,如果在你的init方法中的MyObject中你创建了一个你的类使用的NSMutableArray但是从未调用过init,因为其他人从你的类继承并且从未调用[super init]。然后,每次尝试使用NSMutableArray时,都会有nil引用或错误的指针。设置self等于[super init]的重要原因是self的值可能会发生变化,例如错误恢复。

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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

Wil Shipley建议this(自2009年起):

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

 // other stuff
 return self;
}

但为什么要将超级init的回归分配给自己?

Matt Gallagher的article试图解释它......

- 引用:

  

如果你记得一开始,我   说initWithString:部分   一个典型的[[MyClass alloc]   initWithString:@ “someString”]   调用转换为   objc_msg发送电话:

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

所以当我们到达时   到了方法的内部,自我   已经有了价值;它的价值是    myObject1 (即分配的对象,   从[MyClass alloc]返回   呼叫。这很重要,因为   没有它,超级调用   不可能 - 自我价值   编译器使用它来发送   调用:

[super init];
  

变为:

objc_msgSendSuper(self, @selector(init)); 
  

是的,自我已经   初始化程序时有一个值   开始。事实上,它几乎是   保证是正确的,最终的   值。

- 取消引用

基本上,我认为很多人都对每个init方法的'self'指向的内容感到困惑,直到通过超类链。

这个谜语的答案隐含在Apple的Objective-C Programming Language doc中,名为“指定初始化者”一节:

  

请注意,B版本的init发送了一个   消息给自己调用   initWithName:方法。因此,何时   接收器是B的实例   class,它调用B版本   initWithName:,当接收者   它是C类的一个实例   调用C版本。

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

我是对的吗?当然!