如果 [超级初始化] 返回 nil 该怎么办



>以下代码为例

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

我不希望 nil 向上传播调用层次结构。我最初的想法是在 self 为 nil 的情况下抛出一个异常,建立一个还原点并中止执行。

更好的主意?

NSObject 对[super init]的实现永远不会返回 nil。基本实现只返回 self。

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

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

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

最后,初始值设定项

不是检查超类初始值设定项中失败的正确位置。如果可能出现可恢复的错误,则调用方应检查错误。

例:

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

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

来自文档:-

对于其他类型的错误,包括预期的运行时错误,返回 nil、NO、NULL 或其他一些适合类型的零形式 访客。这些错误的示例包括无法读取或 写入文件,初始化对象失败,无法 建立网络连接,或无法在 收集。如果您认为有必要返回,请使用 NSError 对象 向发件人提供有关错误的补充信息。一个 NSError 对象封装有关错误(包括错误(的信息 代码(可以特定于Mach,POSIX或OSStatus域( 以及特定于程序的信息字典。负值 直接返回的(nil、NO 等(应该是主体 误差指标;如果您确实传达了更具体的错误 信息,则在 方法。

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

如果[super init]返回nil(即无法实例化新对象(,则某些事情会非常混乱,以至于您的应用程序可能会在短时间内崩溃。

按照 Michael 的建议在每次实例化后检查nil很麻烦,并且由于上述原因可能完全无用。

如果您担心某个特定的类,并且您真的想尽快纾困,请按计划继续并抛出例外。

关于">创建还原点",您可以尝试保存任何可能的内容,但该方案受到如此大的损害,无法保证成功。

我想"[super init]"可能会抛出 nil,如果你试图保留一个 20 GB 的内存块或其他东西(没有人做 iOS 编码会这样做(,但一般来说,返回的"nil"很少发生在生产代码中。

返回" nil"的好处是,您可以将消息发送到nil对象,并且您的应用程序不会崩溃。

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

在Apple的"Objective C中的概念"文档中,他们建议"当你创建一个对象时,你一般应该在继续之前检查返回的值是否为nil:">

最新更新