Objective c 目标c,[super init]返回什么?

Objective c 目标c,[super init]返回什么?,objective-c,Objective C,新的目标-c。编写了一段代码片段以更好地理解init机制,最后提出了几个问题 @implementation MyClass -(id) init { if (self) { i = 5; NSLog(@"self before init - %@ %p i=%d",[self className], &self, i); } else { NSLog(@"se

新的目标-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;
    }
i
是一个私有实例变量
int

结果如下:

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
之前初始化实例变量不是一种好的形式,但我只是在尝试


谢谢

您确实需要使用标准模式(或多或少):

您的类是其他类的子类。调用
super init
将运行超类的init例程。如果没有它,您的类将无法正确初始化,并且可能会出现异常故障。(然而,两次调用
super init
可能是不明智的,因为这可能会产生不良的副作用。)

有些情况下,您不会调用
super init
,而是在自己的类中调用
init
的一个版本。基本上,如果你有
initWithJunk:
init
,你可以让
initWithJunk:
调用
[self init]
而不是
[super init]
,这样
self init
就可以完成,而不必在
initWithJunk:
中复制

如果编写一个“category”将
init…
方法添加到现有类中,这一点尤其重要——您必须调用
[self init]
的某个版本,以确保基类的初始值设定项运行

请理解
super init
方法(通常)不是用新实例替换现有实例,而是初始化其中属于超类的实例字段。从
super init
调用返回“self”值的原因有两个:

  • 如果发生某种错误,init例程可以返回
    nil
  • 在某些(罕见的)特殊情况下,init例程可能会将提供的实例替换为不同的实例(例如,缓存版本)

  • 您不应该使用
    &someClass
    ——它返回引用的地址,而不是引用包含的内容。Use
    someClass
    -init在
    +[alloc]
    的结果上被调用,这当然会返回一个(未初始化的)实例
    -init
    不进行分配。@nielsbot说的是真的——您打印的地址是指针变量的地址,而不是变量指向的对象的地址。这可能会引起一些混乱。
    -(id)init {
        self = [super init];
        if (self) {
            // Do initialization stuff
        }
     }