在init方法中使用[self release]、[self dealloc]或[super dealloc]?

12

我刚刚在阅读有关如何正确地在init方法中失败的内容,文档中似乎存在不同的意见。其中一个建议抛出异常,而其他人则建议清理并返回nil。这里当前的最佳实践是什么?

4个回答

16

我认为普遍接受的做法是在失败时返回nil。但你确实想要释放self以避免内存泄漏:

-(id)init
{
  if (self = [super init]) {
    ...
    if (thingsWentWrong) {
      [self release];
      return nil;
    }
    ...
  }
  return self;
}

谢谢大家的反馈。这就是我所做的并且认为是正确的方法,但文档中对其他两种方法的引用让我想到可能需要注意一些特殊情况。 - Kevin

9
正确的解决方案(异常和/或[self release]; return nil;)已经涵盖,接下来我将介绍不正确的解决方案。
不要直接发送dealloc。那是release的工作。(如果您的代码曾在GC下运行,则dealloc无效,并且我只能推测调用它会导致什么问题。)
双重不要使用super直接发送它。这将跳过您自己的dealloc实现。

6

Cocoa的异常理念是,只有在程序员错误的情况下才应该抛出异常,比如向方法传递非法参数。如果其他情况出现问题,该方法应该返回NO或nil,并通过NSError**“out”参数报告详细信息。

这包括-init方法。如果错误情况是完成产品中可能合法发生的事情,那么该方法应该释放self(以避免泄漏)并返回nil。


0

我一直使用的方法是清理并返回nil。你在问题标题中提到的三种方法可能会在调用层次结构更高的位置导致分段错误,而返回nil则不会。我相信Apple文档本身也说在失败时返回nil。你在哪里发现了差异?


2
仅仅返回nil会导致内存泄漏,因为alloc调用将创建一个保留计数为1的对象。 - Marc Charbonneau
内存泄漏是我想要避免的。 - Kevin
初始化期间的错误检测 - http://tr.im/mlyA 实现一个初始化器 - http://tr.im/mlyX您会注意到在第二个链接的示例代码下,他们建议改为抛出异常。我很确定那不是当前的最佳实践。 - Kevin
1
我认为所提到的异常是指在输入为空(非法参数)时抛出异常。我总是使用NSParameterAssert(...)验证方法的参数,即使在init方法中也是如此。这是标准做法,因为它代表了一个编程错误,而不是运行时错误。 - sbooth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接