【问题标题】:objective-c: relying on dealloc目标-c:依赖dealloc
【发布时间】:2012-11-30 02:51:20
【问题描述】:

依赖确定性 dealloc(例如:用于清理)是否合法?

由于 ARC,甚至手动引用计数,本质上是确定性的,我想知道其他人对 依赖 立即调用 dealloc 的看法(相对而言,考虑到 autoreleasepool)。

在其他现代编程语言(如 C#)中,当您需要确定性清理时,会使用类似 dispose 的模式。我会想象带有垃圾收集的 Obj-C 也会鼓励这种行为。

因此,话虽如此,一个示例是 UIViewController,它取消了 dealloc 中的未完成操作,而不是尝试围绕 viewDidDisappear 有时令人沮丧的语义进行编程。

另一个例子是流对象,它分别在 init 和 dealloc 中隐式打开和关闭,而不需要调用 open 或 close。

由于 Apple 已弃用 GC,我想这些模式不会很快被打破,而且它们非常方便,尽管我找不到任何文档说明是否应该鼓励这样做。

【问题讨论】:

    标签: objective-c object memory-management automatic-ref-counting


    【解决方案1】:

    您是绝对正确的,您可以依赖dealloc 在最后一个引用发布后相对较快地被调用(手动或通过 ARC,没关系)。与在系统有空闲时间或在某些情况下从不调用终结器的 GC 不同,dealloc 被非常可靠地调用。 Apple 通过建议我们应该在 dealloc 中执行所有资源清理任务来允许甚至鼓励使用这种模式。

    但这并不意味着您应该完全依赖dealloc。例如,看一下NSStream 类:它为您提供了一个显式的close 方法,让您可以随意强制关闭流,而无需等待dealloc 的调用发生。如果资源非常昂贵(文件句柄、信号量等),这是一个非常好的模式:释放这些资源的主要机制应该是一个单独的close 方法。 dealloc 方法也应该释放资源,但它也应该发出警告,通知您您错过了 close 的调用。

    【讨论】:

      【解决方案2】:

      无论您的内存管理系统如何,将昂贵的资源(例如文件和套接字、图像、视图、大内存分配等)绑定到对象生命周期都是有风险的。即使您手动保留和释放,您也可能在不知不觉中将对象保留在某处并忘记它(或以其他方式不必要地延迟其释放)。 ARC 使这些事情更有可能发生,因为保留的来源以及相应的发布何时生效并不那么明显。当然,GC 使这一切变得完全不确定。

      通常,对于昂贵和/或有限的资源,您应该尝试遵循独资模式。是的,您仍然可以正常保留/释放以防止过早释放,但是应该明确定义主要所有者并负责在完成时清除对象 - 例如调用无效,或关闭,或任何适当的。这在很多常见情况下都非常有意义 - 例如,您通常知道何时完成文件或套接字,因此即使它们恰好封装在某个包装类中,您也应该明确地关闭它们。

      在某些情况下,这还可以帮助找到原本隐藏或难以追踪的错误。例如,如果您的文件包装类在文件关闭后调用 read 或 write 时引发异常,您很快就会发现这些情况。然而,如果您在认为完成文件时没有关闭文件,则读取和写入将照常进行,您可能不会注意到文件中包含意外数据。 p>

      您也可以使用相同的原则来打破保留周期。

      【讨论】:

        猜你喜欢
        • 2023-01-03
        • 2011-07-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-10
        • 2012-10-11
        相关资源
        最近更新 更多