可能重复:
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]实际上做了什么?我很困惑,不能明白这一点
答案 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'变量指向我们的实例(除非明确更改)。
我是对的吗?当然!