如果[super init]返回nil,为什么不抛出异常?

Dan*_*ark 12 cocoa-touch exception objective-c init

这被认为是典型的

- (id)init {
    self = [super init];
    if (self) {
        // <#initializations#>
    }
    return self;
}
Run Code Online (Sandbox Code Playgroud)

但是,与这样的事情做出适当的反应并不是更好吗?

- (id)init {
    self = [super init];
    if (self) {
        // <#initializations#>
    } else {
       @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"you think your constructor is executing, but it's not"] userInfo:nil]
    }
    return self;
}
Run Code Online (Sandbox Code Playgroud)


这个问题的必然结果是,"在什么条件下会[super init]返回nil,你不应该在init方法中处理它? "

Jus*_*Sid 10

不,Objective-C中的异常是指您无法真正恢复的状态,而不仅仅是表明操作失败的状态.如果初始化程序失败,只需返回nil即可显示它.

  • @Yar:但是ObjC相对独特,因为很多语言是按惯例建立的,而不是通过语法建立的.这产生了一种假设,即将遵循某些模式,并且避免模式的测试成为非常高的阈值. (2认同)
  • @Yar嗯,简单的回答是,是的,您应该编写期望_alloc/init_(以及_copy_和其他任何东西)的代码来返回_nil_.答案更长的是不幸的同义词 - 你应该只在你关心的时候关心.如果你的程序的状态完全取决于不是_nil_的东西并且你根本无法恢复它就可以抛出异常,只有你在任何重要的地方都这样做,例如:`MYBar*foo = [[MYBar alloc] initWithData:someData ].NSAssert(foo!= nil,@"不能像这样继续.");` (2认同)

Myr*_*law 10

并不是的.

有:

self = [super init];
Run Code Online (Sandbox Code Playgroud)

你正在调用你的超类init方法,只有在RARE情况下才会返回nil.(如果系统内存不足,你还有其他问题).

if(self)
Run Code Online (Sandbox Code Playgroud)

如果没有返回实例(它是零),这将不会通过,因此不需要else.

旧的方式是

if((self = [super init))
{
    // do initialization
}
return self
Run Code Online (Sandbox Code Playgroud)

编辑:正在阅读Cocoa Fundementals指南,并在错误处理下找到了这个:

如果方法实现中遇到的错误是系统级或Objective-C运行时错误,则在必要时创建并引发异常,并在可能的情况下在本地处理它.在Cocoa中,异常通常保留用于编程或意外的运行时错误,例如越界集合访问,尝试改变不可变对象,发送无效消息以及丢失与窗口服务器的连接.在创建应用程序时而不是在运行时,通常会使用异常处理这些错误.Cocoa预定义了几个异常处理程序可以捕获的异常.有关预定义异常以及用于引发和处理异常的过程和API的信息,请参阅异常编程主题.

对于其他类型的错误,包括预期的运行时错误,返回nil,NO,NULL或其他类型 - 适当的零形式给调用者.这些错误的示例包括无法读取或写入文件,无法初始化对象,无法建立网络连接或无法在集合中查找对象.如果您认为有必要将有关错误的补充信息返回给发件人,请使用NSError对象.NSError对象封装有关错误的信息,包括错误代码(可以特定于Mach,POSIX或OSStatus域)和程序特定信息的字典.直接返回的负值(nil,NO等)应该是错误的主要指标; 如果确实传达了更具体的错误信息,请在方法的参数中间接返回NSError对象.


Vik*_*ica 6

一个原因,为什么你应该这样做,JustSid说的是:

在面向对象的设计中,您应该始终编写代码,就好像您可能会将您的课程交给另一个开发人员的另一个项目.所以你不能假设,他的项目初始化失败可能和你的项目一样糟糕.也许这个开发人员是你5年.想象一下,你想要重用你的麻烦来修复你的200个课程.