为什么我们都在init方法中检查if(self)?

时间:2012-03-15 11:53:38

标签: objective-c cocoa-touch cocoa initialization

我已经虔诚地做了几年了。在调用self方法后检查[super init...]的有效性:

self = [super init];
if (self != nil) {
    // initialize
}
return self;

你可以用各种方式做到这一点,因为this question很好地总结了,但这个问题是关于语法的,我的是关于概念的。

我最近从一位正在学习Objective-C的同事那里得到了一个问题,他问我“我为什么要测试自我的存在,是不是很明显它在那里?”而我的简短回答是“错误,是的,那里有可能失败的情况,所以这就是原因。”但是很长的答案是,我真的不明白自己为什么要在任何地方进行测试,因为它可能失败的情况非常罕见。 Apple's reference guide告诉我们一些特定情况,例如初始化文件或处理单例时。但这听起来像[super init] s应该起作用的规则非常罕见。

所以我的问题是:为什么我们总是测试自我的有效性?我们是否只是在任何地方实现它以捕获它发生的那个例外?为什么不跳过整个if (self)事物并初始化我们的对象,如果它成功的机会是100%(或者从来没有这种情况)?

P.S。我意识到这个问题必须是一个骗局,因为它是如此基本,但我的搜索查询还有很多关于初始化语法的其他问题。 Dupe链接很受欢迎,欢呼!

2 个答案:

答案 0 :(得分:7)

这是关于这个问题的a helpful old article,还包括一些关于初始化程序的常见误解。我要说的基本思想是,一个特定的类不应该关注它的超类的实现,所以我们总是在出错时检查nil

答案 1 :(得分:1)

嗯......这绝对是一个很好的问题,我希望我已经成功了。 我不是Objective-c的专家,但我会尽量给出我的意见,而不用担心downvoter :-)

我可以感受到你的沮丧但是:

err, yeah, well there's instances where it can fail, so that's why.

这是一个非常好的答案。 我认为你没有检查自己,但你正在检查超级对象是否正确初始化,对我来说这是一个不同的观点。

我认为在任何情况下检查对象是否已经正确分配和初始化总是好的做法,尤其是在Objective-c中,它位于C之上,具有所有伪装内存分配问题。初始化在'alloc'之后,它应该用变量等初始化分配的对象......

例如,在像Java这样的语言中,编译器链很好地定义并由编译器检查,如果不能构造对象,则在以后使用该对象时将导致空指针错误。通常,Java中对象的分配是没有错误的,但是经常使用方法必须包含ad hoc try / catch错误块。因此,检查将在应用程序生命周期的后期进行。

在objective-c中,您可能出于多种原因而拥有一个nil对象,如果没有应用程序崩溃,您可以结束向无效对象发送消息。 我必须诚实,当直接从NSObject的子类实例化时,我不知道检查nil的效用。但是如果我在框架中扩展一个类,或者在其他人提供的静态库中扩展,我肯定会对检查对象的有效性感到安全。