【问题标题】:[self release], [self dealloc] or [super dealloc] in init methods?init 方法中的 [self release]、[self dealloc] 或 [super dealloc]?
【发布时间】:2009-05-25 16:25:09
【问题描述】:

我刚刚阅读了有关如何在 init 方法中正确失败的信息,并且文档似乎彼此不同意。一个建议抛出异常,而另一些建议清理并返回 nil。目前这里的最佳做法是什么?

【问题讨论】:

    标签: objective-c cocoa


    【解决方案1】:

    我相信普遍接受的做法是在失败时返回 nil。但是您确实想释放 self 以避免泄漏:

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

    【讨论】:

    • 感谢大家的反馈。这是我正在做的事情,并且认为这是正确的方法,但文档中对其他两种方法的引用让我认为可能有一些特殊情况需要注意。
    【解决方案2】:

    已涵盖正确的解决方案(异常和/或[self release]; return nil;),我将解决不正确的解决方案。

    不要直接发送dealloc。那是release 的工作。 (如果你的代码曾经在 GC 下运行,dealloc 是不适用的,我只能推测调用它会导致什么问题。)

    双重-不要使用super直接发送。这将跳过您自己的 dealloc 实现。

    【讨论】:

      【解决方案3】:

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

      这包括 -init 方法。如果错误情况可能在成品中合法发生,则该方法应释放自身(以避免泄漏)并返回 nil。

      【讨论】:

        【解决方案4】:

        我一直使用的方法是清理并返回 nil。您在问题标题中提到的三种方法可能会导致调用层次结构中更高的段错误,而返回 nil 不会。我相信苹果文档自己说失败时返回零。您在哪里发现差异?

        【讨论】:

        • 简单地返回 nil 会泄漏内存,因为对 alloc 的调用将创建一个保留计数为 1 的对象。
        • 内存泄漏是我想要避免的。
        • 链接到文档:初始化期间的错误检测 - tr.im/mlyA 实现初始化程序 - tr.im/mlyX 您会注意到,在第二个链接中的示例代码下,他们建议改为抛出异常。我很确定这不是当前的最佳做法。
        • 我相信所指的异常意味着如果输入为 nil(非法参数)则抛出异常。我总是使用 NSParameterAssert(...) 验证我的方法的参数,即使在 init 方法中也是如此。这是标准做法,因为它代表的是编程错误,而不是运行时错误。
        猜你喜欢
        • 2011-09-29
        • 1970-01-01
        • 2011-03-04
        • 2013-11-23
        • 1970-01-01
        • 2023-04-07
        • 2012-03-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多