13

在书中,我看到如果子类覆盖超类的方法,我们可能有

self = [super init];

首先,这应该在子类的init方法中完成吗?

二、不知道为什么调用不只是

[super init];

? 我的意思是,在调用init时,内存已经分配了alloc(我认为子类的名称[Foobar alloc]在哪里Foobar。所以我们不能只调用[super init]来初始化成员变量吗?为什么我们必须获取的返回值init并分配to self? 我的意思是,在调用之前[super init]self应该指向一个有效的内存分配卡盘......那么为什么要再次为 self 分配一些东西呢?

(如果分配,不会[super init]只返回self现有值吗?)

4

4 回答 4

11

那么为什么要将[super init]返回的值赋给self呢?看一个典型的初始化方法:

 - (id)initWithString:(NSString *)aString {
     self = [super init];
     if (self)
     {
         instanceString = [aString retain];
     }
     return self; }

为什么我们在这里将 [super init] 分配给 self ?

教科书的原因是因为 [super init] 被允许做以下三件事之一:

  1. 返回它自己的接收器(self 指针不变)并初始化继承的实例值。
  2. 返回具有初始化继承实例值的不同对象。
  3. 返回 nil,表示失败。

在第一种情况下,赋值对 self 没有影响,并且在原始对象中设置了 instanceString(行 instanceString = [aString retain]; 可能是方法的第一行,结果将是相同的)。

第三种情况,初始化失败。self 设置为 nil,不采取进一步行动并返回 nil。

分配给 self 的基本原理与第二种情况有关:如果返回的对象不同,我们想要:

instanceString = [aString retain]; which gets converted to

self->instanceString = [aString retain]; to act on the correct value,

所以我们必须改变 self 的值来指向这个新对象。

希望这会有所帮助...

来自 Cocoa with Love

于 2012-04-13T11:24:09.220 回答
3

返回不同对象的一个​​经典示例-init是实现类集群 - 一个抽象接口,具有多个提供不同存储或算法的具体实现者。+[NSString alloc]返回 的实例NSPlaceholderString。占位符实例的初始化器检查它们的参数,释放占位符字符串并返回具体子类的初始化实例NSString

于 2012-04-13T11:43:09.347 回答
2

超类可能会决定对象无法正确初始化并返回 nil 作为失败。如果您不将 nil 分配给 self 您的 init 方法将在父类已正确初始化对象的假设下继续进行。

如果需要,父类也可以返回完全不同的对象。

于 2012-04-13T11:23:43.927 回答
2

了解对象已经分配并且 self 指向内存。

现在 [super init] 执行初始化部分。

1)如果初始化成功,则self在初始化之前指向同一个对象

2) 如果初始化失败,init 函数返回 nil 并且 self = nil。现在我们可以检查对象是否已初始化,如果是,请通过此代码执行我们的魔法

 if(self = [super init]){
  // do our magic
 }

它就像我们使用一个imageView,我们通常使用

UIImageView imgView = [[UIImageView alloc] init];

如果 alloc 和 init 都成功,imgView 将只有非 nil 值。

于 2012-04-13T11:31:07.767 回答