Objective c 在初始化对象时使用Super

Objective c 在初始化对象时使用Super,objective-c,memory-management,super,Objective C,Memory Management,Super,可能重复: 我真的无法理解super在初始化对象时的作用。 例如,有以下代码(示例-不是我写的): [super init]实际上做什么?我很困惑,无法理解这一点,因为Objective-C是面向对象的,所以您可以从其他类继承,因此有必要确保正确初始化从MyObject的超类继承的实例变量。当您从其他类继承时,您可以截取消息并决定是否将它们传递给您从中继承的类。对于init,执行self=[super init]或使用类的指定init方法来确保正确创建对象几乎总是非常重要的。想象一下,如果在i

可能重复:

我真的无法理解super在初始化对象时的作用。 例如,有以下代码(示例-不是我写的):


[super init]实际上做什么?我很困惑,无法理解这一点,因为Objective-C是面向对象的,所以您可以从其他类继承,因此有必要确保正确初始化从MyObject的超类继承的实例变量。当您从其他类继承时,您可以截取消息并决定是否将它们传递给您从中继承的类。对于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;
}
Wil Shipley建议(从2009年起):

但为什么要将super init的返回指定给self呢

马特·加拉赫试图解释

--引述:

如果你记得一开始,我 说初始字符串:部分 典型的[[MyClass alloc] initWithString:@“someString”] 调用被转换为 objc_msgSend调用:

所以当我们到达 在方法的内部,self 已经有了价值;它的价值是 MyObject 1(即分配的对象, 从[MyClass alloc]返回 打电话。这很重要,因为 没有它,超级调用 不可能——自我价值观 由编译器用来发送 调用:

变成:

是的,self已经 当您的初始值设定项 开始。事实上,它几乎是 保证是正确的,最终的 价值观

--取消报价

从本质上讲,我认为很多人对每个init方法的“self”在超类链中到底指向什么感到困惑

苹果公司在标题为“指定初始值设定人”的章节中暗示了这个谜团的答案:

注意,init的B版本发送一个 向self发送消息以调用 initWithName:method。因此,当 接收器是B的一个实例 类,它调用的B版本 initWithName:,并且当接收器 是C类的一个实例,它 调用C版本

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


我说的对吗?当然!

你指的是我省略了
if((self=[super init])的必要性。
?看起来海报理解条件,但我可以编辑。是的——一定有人会不假思索地复制它。。。
//this is valid
-(id)init
{
   if((self = [super init]))
   {
       if(someInitializationFails)
       {
           [self release];
           self = nil;
       }
   }
   return self;
}
- (id)init;
{
 if (!(self = [super init]))
   return nil;

 // other stuff
 return self;
}
MyClass *myObject2 = objc_msgSend(myObject1, initSelector, @"someString"); 
[super init];
objc_msgSendSuper(self, @selector(init));