2013-09-28 29 views
4

以下面的代码为例如果[super init]返回nil该怎么办?

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

我不想零传播了调用层次结构。我最初的想法是抛出一个例外情况,以防止自己是零,做一个还原点并放弃执行。

更好的主意?

+0

一种侧面的问题 - 但你是什么意思通过做一个还原点? –

+0

@CarlVeazey将任何未保存的数据保存到临时文件 –

+2

我会仔细考虑保存数据是否真的会帮助或伤害用户。如果你在这种情况下得到“nil”,很明显是因为你的应用程序已经脱轨。内存中的数据很可能已经损坏。除非你能够明确地验证这些数据*或*你的应用程序提供了一些版本加载的方法,那么你可以简单地销毁最后的有效保存。 – bbum

回答

8

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

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

致命错误通常会引发异常或中止程序。所以检查零对他们没有帮助。处理致命错误的最佳方法是NSSetUncaughtExceptionHandler,但您应该意识到,在致命错误的情况下保存数据是有风险的,因为未保存的数据可能已损坏。在这种情况下不要覆盖好数据。

为什么objective-c代码始终在初始化程序中检查nil,即使super不会返回nil?公约,大多数。可以说,通过总是检查零,超类更容易在将来添加失败条件,而不需要更改子类,但实际上这只是一个约定。

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

实施例:

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

检查零每当你初始化对象是矫枉过正。这只需要在存在error:参数时完成,或者该方法具有可记录的可恢复错误。

+0

很好的答案,完全同意。 –

4

从文档: -

对于其他种类的错误,包括预期的运行时错误,返回 零,NO,NULL,或一些其他类型 - 的零合适的形式向 呼叫者。这些错误的示例包括无法读取或写入文件,初始化对象失败,无法建立网络连接或无法在 集合中查找对象。如果您觉得有必要将有关错误的补充信息返回 给发件人,请使用NSError对象。一个NSError 对象封装有关错误的信息,其中包括错误 代码(可能是特定于Mach,POSIX或OSStatus域的) 和程序特定信息的字典。直接返回的负值 (无,NO等)应该是主要的 错误指示符;如果您确实通信了更多特定错误 信息,则在 方法的参数中间接返回一个NSError对象。

2

我想“[super init]”可能会引发零,如果你想保留的内存什么的(没人在做iOS的编码会做)20块演出,但在一般情况下,“nil”返回在生产代码中很少发生。

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

但是,在实例化一个对象之后,您应该始终对nil进行检查,以确保您的应用程序(或您的用户)无法从中恢复过来。

Apple's "Concepts in Objective C" document,他们建议“当你创建一个对象时,通常应该检查返回的值是否为零,然后继续:”

+0

iOS设备的内存有限。该应用程序不会崩溃,但可能会有不需要的行为。 –

+0

*实例化一个对象*之后,您应该始终检查'nil'。听起来很疯狂。你检查然后是什么?如果你不能实例化对象,就放弃并接受崩溃,因为你确实没有什么可以做的。 –

+0

苹果实际上说在初始化后检查零,@GabrielePetronella。我修改了我的答案以指出文档。 –

4

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

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

根据Michael的建议,在每个实例化之后检查nil是麻烦的,并且由于上述原因可能完全无用。

如果您担心某个特定班级,并且您确实希望尽快获得救助,请按照您的计划行事并抛出异常。

关于“制作还原点”,您可以尝试保存任何可能的内容,但该方案如此受损,以致无法保证成功。

相关问题