6

init对象分配后真的有必要调用吗?我的意思是:例如,在 Java 中,如果您不调用它(构造函数),无论如何都会调用它(默认构造函数)。在 Objective C 中,您可以创建一个替代构造函数(如 Java),而我看到最多的东西之一是self = [super init]. 我读过:cocoawithlove 文章,但最后不清楚我们为什么要进行这样的分配self = [super init]。它只是说[super init]可以返回一个不同的对象,然后我们必须self用那个新对象替换 。这无法解释为什么我们首先要这样做。

4

3 回答 3

5

对象分配后真的有必要调用init吗?

是的,这是必要的。为了与 Java 进行比较,调用[super init](或其他一些指定的初始化程序)有效地运行超类的构造函数。在 Java 中为您提供了这种机制,但在 Objective-C 中没有。所以它不像在 Java 中那样在 ObjC 中被隐式调用。在 ObjC 中,您必须显式调用超类的指定初始化程序之一。如果你不调用你的超类的初始化器,你的对象将不会被完全初始化。这可能不会导致任何副作用,或者可能会导致调用未定义行为的完全不可用的对象。

为什么我们应该做这样的赋值 self = [super init]。

对,alloc创建一个分配(内存归零)并设置指向类信息的指针isa,但是超类的初始化器允许超类与另一个可能更合适的交换实例。通常,您会避免在自己的子类中这样做。执行此操作和 nil 检查的另一个原因是它是处理错误的方法。在 ObjC 中,异常一般是不可恢复的,因此向子类报告错误的常规方式是 return nil。这就是为什么不仅分配self,而且测试它也很重要nil

于 2012-09-04T13:29:53.753 回答
3

Objective C 和 Java 之间有很大的不同。Java 是一种从头开始构建的解释性语言,而 Objective C 是建立在 C 语言之上的。你可以在 C 中做的任何事情在 Objective C 中也是有效的。

与 Java 不同,C(以及扩展的 Objective C)具有“原始内存分配”。在 Java 中,调用会new 自动调用构造函数。该语言使绕过这种机制成为不可能。然而,在 Objective C 中,您可以分配原始内存。内存在返回给您时不包含随时可用的对象alloc- 它只是部分准备好使用。内存块有一个引用计数,它提供了足够的空间来容纳你的对象,但它还没有准备好接收你自己的子类已经实现的消息。这就是为什么您必须调用init(或使用new,它结合了allocinit)。

if (self = [super init])分配/检查使您可以在对象的构造阶段捕获错误。如果您自己的初始化程序失败,您可以设置self = nil为向上报告问题。分配不同的对象要少得多,但也可以这样做。

于 2012-09-04T13:34:50.717 回答
2

分配后实例变量应该被实例化。 self = [super init]指初始化超类init方法

一个常见的错误是写

self = [[super alloc] init]; 它返回超类的实例,这不是您在子类构造函数/init 中想要的。你得到一个不响应子类方法的对象,这可能会令人困惑,并会产生关于不响应方法或未找到标识符等的令人困惑的错误。

self = [super init] 如果超类有成员(变量或其他对象)在设置子类的成员之前首先初始化,则需要。否则,objc 运行时会将它们全部初始化为 0 或 nil。(不像 ANSI C,它经常分配内存块而不清除它们)

是的,基类初始化可能会由于内存不足错误、缺少组件、资源获取失败等而失败,因此检查 nil 是明智的,并且只需不到几毫秒。

于 2012-09-04T13:30:08.653 回答