在iOS6之前使用ARC时,仍然需要“dealloc”和“viewDidUnload”方法吗?

时间:2012-09-27 21:56:29

标签: ios automatic-ref-counting xcode4.5

我是一个负责iOS遗留代码的大型团队的一员,目标iOS环境为4.3及更高版本。我见过其他开发人员检查来自NSObject但没有dealloc方法的类。我还看到了不包含UIViewController方法的viewDidUnload个后代。当我询问这段代码时,通常的回答是“别担心,ARC现在负责处理。”

我理解当iOS遇到内存不足的情况时会调用viewDidUnload,其目标是通过调用viewDidLoad释放可以重新创建的对象来释放内存,而dealloc是当对象的保留计数达到零时调用。对于UIViewController对象和后代,这可能意味着在dealloc之前可能会或可能不会调用'viewDidUnload'。

所以这是我的问题:在iOS 6之前的iOS版本上使用ARC时,仍然需要deallocviewDidUnload方法吗?

如果答案是“是!”,那么我需要充分的理由和/或文件来进行论证。

期待您的回复。 (感谢Tommy帮助我收紧我的问题。)

2 个答案:

答案 0 :(得分:14)

viewDidUnload is deprecated。因此,无论ARC如何,您不仅不需要一个,而且不应该使用一个。陈述的理由是视图不再被低内存警告清除(大概是因为它们现在对总数的贡献太小而不值得响应性命中);如果部分理由是很多人认为他们可以在viewDidLoad内释放viewDidUnload中创建的所有资源,那么我就不会感到惊讶,仅此一项就可以防止泄密。这不是真的,因为viewDidUnload是 仅在视图由于内存不足警告而卸载时调用。它不会在正常生命周期中调用。

ARC's new rules下:

  

如果需要管理资源,可以实现dealloc方法   除了释放实例变量。你不必(确实如此)   你不能发布实例变量

编辑:专门评论4.3+ ......

ARC不会为您实施viewDidUnload版本。 viewDidLoad / viewDidUnload周期的重点是,如果您出于任何原因retain视图层次结构的任何部分,那么您将导致在内存不足警告时不会自动释放,但这样做不会给你带来任何好处,因为一旦下次加载视图,你保留的内容将被替换为新副本。因此,如果strong IBOutlet位于self.view下面的层次结构中,那么理想情况下,您会在viewDidUnload期间将它们排除在外。即使你有weak个参考文献,也是防止你继续发扬任何悬空指针的好地方。

从iOS 5开始,您可以使用自我归零的弱引用,因此如果您支持5+,那么使用这些引用并不实现viewDidUnload将是您的选择。对于4.3,如果您使用强引用并省略viewDidUnload,您最终可能会像Apple希望的那样彻底避免对低内存警告的响应,但您不会泄漏内存。如果你使用弱引用,那么当你可能没有视图时,你需要小心不要引用任何这些对象(即,任何时候你没有显示但视图先前已加载 - setters控制器上也调整视图但受其他视图影响的是一个典型的例子;比如说你是否通过键值观察来更新字段。

您可以使用模拟器的“模拟内存警告”来测试和调试这些内容。

无论iOS版本如何,ARC提供的dealloc都是相同的。但是它只包含Objective-C对象。当他们说你无法释放实例变量时,他们就意味着它将release消息发送给他们。假设您有Core Foundation对象或已执行纯C内存分配,那么您将需要实现一个dealloc来处理所有这些。

显然,仪器和泄漏工具是测试和调试该区域的方法;在任何时候内存泄漏时要小心,以检查创建该内存的对象类型是否也被泄露。直接对象可以没问题,但如果它没有dealloc,它的分配将出现在泄漏列表上,因为有人泄露了它。

答案 1 :(得分:6)

viewDidUnload现已弃用,系统不再调用(从iOS 6开始)。它从未像苹果希望的那样有用,而且比它的价值更麻烦。这与ARC无关。

ARC下通常不需要

dealloc,但在需要非ARC资源管理的情况下仍然是必需的。例如,如果您需要使用free(),或以其他方式释放资源。它也是一个将自己视为观察者或代表的好地方。但是现在很多课程都不需要dealloc