objective-c新手。编写了一个代码片段来更好地理解init机制,最后提出了几个问题。
@implementation MyClass
-(id) init
{
if (self) {
i = 5;
NSLog(@"self before init - %@ %p i=%d",[self className], &self, i);
} else {
NSLog(@"self is null???");
}
id someClass = [super init];
NSLog(@"the result of super-init - %@ %p",[someClass className], &someClass);
self = [super init];
if (self) {
NSLog(@"self after init - %@ %p %d",[self className], &self, i);
} else {
NSLog(@"self is null???");
}
return self;
}
CCD_ 1是私有实例变量CCD_。
结果如下:
2012-12-14 18:01:26.403 Init[1621:303] self before init - MyClass 0x7fff5fbff848 i=5
2012-12-14 18:01:26.405 Init[1621:303] the result of super-init - MyClass 0x7fff5fbff838
2012-12-14 18:01:26.405 Init[1621:303] self after init - MyClass 0x7fff5fbff848 5
真正让我惊讶的是someClass的类名是MyClass
。
NSObject
如何知道返回子类实例(不仅仅是类型匹配,它是完全相同的对象)
我知道多次调用init
并在调用init
之前初始化实例变量是不好的,但我只是在尝试。
谢谢。
您确实需要使用标准schemen(或多或少):
-(id)init {
self = [super init];
if (self) {
// Do initialization stuff
}
}
您的类将其他类划分为子类。对super init
的调用运行超类的init例程。如果没有它,你的类就无法正确初始化,可能会出现奇怪的故障。(然而,两次调用super init
可能并不明智,因为这可能会产生不良副作用。)
在某些情况下,您不会调用super init
,而是在自己的类中调用i
0的一个版本。基本上,如果你有initWithJunk:
和init
,你可以让initWithJunk:
调用[self init]
而不是[super init]
,这样self init
会做的事情就完成了,不必在initWithJunk:
中复制。
如果您编写了一个将init...
方法添加到现有类中的"类别",那么这一点尤其重要——您必须调用某个版本的[self init]
,以确保基类的初始值设定项运行。
要理解,int
0方法(通常)不是用新实例替换现有实例,而是初始化其中属于超类的实例字段。从super init
调用返回"self"值的原因有两个:
- 如果发生某种错误,init例程可以返回
nil
- 在某些(罕见的)特殊情况下,init例程可能会用不同的实例(例如缓存版本)替换提供的实例