Objective c 为什么我要调用self=[super init]
假设我创建了我的类及其Objective c 为什么我要调用self=[super init],objective-c,Objective C,假设我创建了我的类及其init方法。为什么我要调用并返回分配给self的超类init的值?它包括哪些案例 我希望能举一些例子说明为什么我需要它作为Cocoa超类和非Cocoa对象。因为你必须以某种方式初始化对象,而且你可能想做任何需要初始化的超类,因为你是从它下降的。你是说为什么 self = [super init]; 而不是 [super init]; 原因有二: 在初始化过程中,返回nil表示失败。您需要知道超级对象的初始化是否失败 超类可能会选择用不同的对象替换+alloc返回的se
init
方法。为什么我要调用并返回分配给self的超类init
的值?它包括哪些案例
我希望能举一些例子说明为什么我需要它作为Cocoa超类和非Cocoa对象。因为你必须以某种方式初始化对象,而且你可能想做任何需要初始化的超类,因为你是从它下降的。你是说为什么
self = [super init];
而不是
[super init];
原因有二:
-(id) init
{
self = [super init];
if (self != nil)
{
myBoolIvar = YES;
// The above is an implicit version of self->myBoolIvar = YES;
}
return self;
}
赛尔夫显然指向了正确的记忆块,即你要返回的那块
另一点是,如果super init返回不同的类实例,那么该行之后的其余代码甚至可能没有意义,导致内存泄漏和崩溃,甚至不涉及从该类实例化的对象
这可能是个问题。如果我将NSNumber子类化,[super init]决定返回一个NSString(它可以-没有什么可以阻止它),那显然是一场灾难。无论从-init返回什么样的超类,都必须与子类“兼容”,即为IVAR提供空间并进一步子类化,否则这是一个可怕的错误(当然,除非有记录)。因此,一般来说,您不需要担心检查类。但是,请务必阅读文档。例如,请参阅NSString文档中有关NSString子类化的部分。在大多数情况下,将self设置为[super init]没有任何作用,因为[super init]最终将返回self。然而,在一些罕见的情况下,[super init]会返回不同的结果。如果由于某种原因未能初始化超类,它可能返回nil,或者它可能决定返回一个完全不同的对象。我知道现在回答有点晚了,但我无法阻止自己发布一个链接,我发现这个链接对于消除我对这个问题的疑虑非常有用 编辑:根据评论,以下是链接中的要点 了解为什么
self=[super init]代码>我们需要考虑很多要点。让我们一个接一个地解决它
什么是self
每个方法都有两个隐藏参数:self
和\u cmd
。所以方法调用
- (id)initWithString:(NSString *)aString
由编译器更改为如下函数调用
id initWithString(id self, SEL _cmd, NSString *aString);
void setValueToZero(id self, SEL _cmd)
{
self->value = 0;
}
为什么我们需要自我?
事实上,编译器使用self
参数来解析方法中对实例变量的任何引用
假设我们有一个方法setValueToZero
,并且value
是它所属类的一个实例变量,那么实现
- (void)setValueToZero
{
value = 0;
}
将由编译器转换为如下函数
id initWithString(id self, SEL _cmd, NSString *aString);
void setValueToZero(id self, SEL _cmd)
{
self->value = 0;
}
Doself
在调用init
时是否已经有值?
下面是一个典型的对象创建和初始化示例
[[MyClass alloc] initWithString:@"someString"]
在这里,当我们进入initWithString
方法时,self将把新分配的对象作为其值(即[MyClass alloc]
的返回值)。事实上,几乎可以保证它是正确的最终值
为什么self=[super init]代码>?
这是因为[super init]
被允许做以下三件事之一:
使用初始化的继承实例值返回它自己的接收器(self
指针不改变)
nil
,表示失败自我
没有影响。在第三种情况下,初始化失败,self
设置为nil
,并返回
分配给self
的原因在于第二种情况。考虑下面的
- (id)initWithString:(NSString *)aString
{
self = [super init];
if (self)
{
instanceString = [aString retain];
}
return self;
}
我们希望从
instanceString = [aString retain];
到
要根据正确的值进行操作,因此我们必须更改self
的值
什么时候[super init]
会返回不同的对象?
在下列情况之一
[NSNumber numberWithInteger:0]
始终返回全局“零”对象)- (id)initWithString:(NSString *)aString
{
id result = [super init];
if (self == result)
{
instanceString = [aString retain];
}
return result;
}
结论
您无需将[super init]
分配给self
即可使大多数类正常工作。在一些模糊的情况下,这样做实际上是错误的
那么,为什么我们要继续分配给
self
?它是初始值设定项的传统模板,虽然在某些情况下它是错误的,但在其他情况下它是正确的,因为编写这种方法时,它是正确的。基本上每个Objective-C类