如果[super init]返回nil怎么办?

时间:2013-09-28 19:43:41

标签: objective-c

以下面的代码为例

- (id)init {
    self = [super init];
    if (self) {
        // code
    }
    return self;
}

我不希望nil传播调用层次结构。我最初的想法是抛出一个异常,以防self为零,建立一个恢复点并中止执行。

更好的想法?

4 个答案:

答案 0 :(得分:9)

NSObject的[super init]实现永远不会返回nil。 The base implementation just returns self

通常,初始化程序返回nil的唯一原因是发生了非致命错误。例如,您可能已调用-initWithContentsOfURL:error:并传递了无效的网址。按照惯例,可能以这种方式失败的方法具有error:参数,其中包含有关失败的信息。大多数初始化程序都没有可恢复错误的可能性,因此像NSObject一样,它们永远不会返回nil。

致命错误通常会抛出异常或中止程序。因此检查nil对他们没有帮助。处理致命错误的最佳选择是NSSetUncaughtExceptionHandler,尽管您应该知道在发生致命错误的情况下保存数据存在风险,因为未保存的数据可能已损坏。在这种情况下,不要覆盖好的数据。

为什么objective-c代码总是在初始值设定项中检查nil,即使super永远不会返回nil?公约,主要是。可以说,通过始终检查nil,超类在将来添加失败条件变得更容易,而不需要更改子类,但实际上它只是一个约定。

最后,initalizer不是检查超类初始化程序失败的正确位置。如果可能出现可恢复的错误,则调用者应检查错误。

示例:

NSError *error;
FooClass *myFoo = [[FooClass alloc] initWithContentsOfURL:blah error:&error]
if (myFoo == nil) {
  // ...
} else {
  // ...
}

初始化对象时检查nil是否过度。只有在存在error:参数时才需要执行此操作,或者该方法具有记录的可恢复错误。

答案 1 :(得分:4)

来自文档: -

  

对于其他类型的错误,包括预期的运行时错误,返回   nil,NO,NULL或其他类型 - 适合的零形式   呼叫者。这些错误的例子包括无法阅读或   写一个文件,初始化一个对象失败,无法做到   建立网络连接,或无法找到对象   采集。如果您觉得有必要返回,请使用NSError对象   有关错误的补充信息给发件人。一个NSError   object封装有关错误的信息,包括错误   代码(可以特定于Mach,POSIX或OSStatus域)   以及程序特定信息的字典。负值   直接返回(nil,NO等)应该是主体   错误指标;如果你确实传达了更具体的错误   信息,间接返回一个NSError对象的参数   方法

答案 2 :(得分:4)

一般来说,只是不在乎让nil传播。

如果[super init]正在返回nil(即无法实例化新对象),那么某些内容会非常糟糕,以至于您的应用程序可能会在短时间内崩溃。

按照迈克尔的建议,在每次实例化后检查nil都很麻烦,而且由于上述原因可能完全没用。

如果您担心某个特定课程,并且您真的想尽快拯救,请按照您的计划继续进行并抛出异常。

关于“制作还原点”,您可以尝试保存任何可能的内容,但这种情况会受到影响,因此无法保证成功。

答案 3 :(得分:2)

我认为“[super init]”如果你试图保留一个20 gig的内存块或其他东西(没有人会做iOS编码的话)就可以抛出nil,但总的来说,“{{1} “返回很少发生在生产代码中。

返回“nil”的好处是你可以向nil对象发送消息,你的应用程序不会崩溃。

但在实例化对象后,您应该始终对nil进行检查,以确保您不会太深入了解您的应用(或您的用户)无法恢复的内容。

Apple's "Concepts in Objective C" document中,他们建议“当您创建对象时,通常应该在继续之前检查返回的值是否为nil:”