【问题标题】:Super in initializing objects [duplicate]超级初始化对象[重复]
【发布时间】:2011-05-19 20:25:54
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: objective-c memory-management super


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 你指的是我忽略了if((self = [super init]))的必要性?看起来发帖人理解了条件,但我可以编辑。
      • 是的——有人一定会不假思索地复制意大利面……
      【解决方案3】:

      Wil Shipley 推荐 this(自 2009 年起):

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

      但是为什么要把 super init 的 return 分配给 self 呢?

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

      -- 引用:

      如果你还记得一开始,我 表示 initWithString: 的一部分 一个典型的 [[MyClass alloc] initWithString:@"someString"] 调用被转换为 objc_msg发送调用:

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

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

      [super init];
      

      变成:

      objc_msgSendSuper(self, @selector(init)); 
      

      是的,自己已经 当你的初始化器有一个值 开始。其实差不多 保证是正确的,最终的 价值。

      -- 取消引用

      基本上,我认为很多人对每个 init 方法的“自我”到底指向什么感到困惑,通过超类链向上。

      Apple 的 Objective-C Programming Language doc 中标题为“指定初始化程序”的部分下暗示了这个谜题的答案:

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

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

      我说的对吗?当然!

      【讨论】:

        猜你喜欢
        • 2012-01-17
        • 2012-04-27
        • 1970-01-01
        • 2015-12-03
        • 1970-01-01
        • 2013-07-23
        • 1970-01-01
        • 1970-01-01
        • 2015-05-24
        相关资源
        最近更新 更多