繁体   English   中英

Objective-c:依赖dealloc

[英]objective-c: relying on dealloc

依赖确定性的 dealloc(例如:用于清理)是一种合法的做法吗?

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

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

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

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

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

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

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

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

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

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

您还可以使用相同的原则来打破保留循环。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM