在使用ARC之前,iOS6之前还需要'dealloc'和'viewDidUnload'方法吗?

问题描述:

我作为一个工作在iOS遗留代码上的大团队的一员工作,目标iOS环境为4.3及更高版本。我看到其他开发人员检查从NSObject下降的类,但没有dealloc方法。我也看到UIViewController后代不包括viewDidUnload方法。当我询问这个​​代码时,通常的回答是“别担心,ARC现在就照顾好这个。”在使用ARC之前,iOS6之前还需要'dealloc'和'viewDidUnload'方法吗?

我明白viewDidUnload通过调用viewDidLoad调用时的iOS经验内存不足的条件下,通过释放可重新创建的对象释放内存的一个目标,当一个对象的保留计数降为零dealloc被调用。对于UIViewController对象和后代,这可能意味着'viewDidUnload'可能会或可能不会在dealloc之前被调用。

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

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

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

viewDidUnloadis deprecated。所以不管是ARC,你不仅需要一个,而且不应该使用一个。陈述的理由是观点不再被低清记忆警告清除(可能是因为他们现在贡献得太少而不值得响应命中);如果部分理由是,许多人认为他们可以释放在viewDidUnload之内的viewDidLoad中创建的所有资源,并且仅凭这一点就可以防止泄漏,我不会感到惊讶。这是不正确的,因为viewDidUnload是 只有在卸载视图时才会调用,因为内存不足警告。它在正常生命周期中不被调用。

ARC's new rules

,如果你需要管理比释放实例变量 其他资源,您可以实现一个dealloc方法。你不必(实际上 你不能)释放实例变量

编辑:4.3及更高版本上专门发表评论......

ARC将不执行一个版本的viewDidUnload你。viewDidLoad/viewDidUnload周期的一点是,如果因为任何原因视图层次结构的任何部分出现故障,那么在低内存警告时不会自动释放,但这样做不会给您带来任何好处,因为只要视图下一次加载,您保留的任何内容都将被替换为新的副本。因此,如果您有strongIBOutlet s的观点,无论如何都应该在self.view之下的层次结构内,那么最好在viewDidUnload期间将它们清零。即使你有weak参考,这是一个很好的地方,以防止自己发扬任何悬挂指针。

从iOS 5开始,你可以拥有自我调零的弱引用,所以如果你支持5+,那么使用这些引用并且不执行viewDidUnload将是一种好方法。如果您使用强引用并忽略viewDidUnload,则4.3可能最终会阻止您完全响应Apple提供的低内存警告,但您不会泄漏内存。如果你使用弱引用,那么在有时候你可能没有视图的时候,你需要小心不要引用任何这些对象(也就是说,任何时候你没有显示,但视图之前已经加载 - setters在调整视图但受另一个视图影响的控制器上也是一个典型示例;例如,如果您正在通过键值观察来更新字段)。

您可以使用模拟器的“模拟内存警告”在一定程度上测试和调试这些内容。

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

很明显,Instruments和Leaks工具是测试和调试该区域的方法;任何时候内存泄漏都要小心,以检查创建该内存的对象的类型是否也在泄漏。直接对象可以很好,但是它的分配会出现在泄漏列表中,如果它不是dealloc,因为有人泄漏了它。

+0

对不起,@Tommy,我对目标iOS版本的问题还不够清楚。将根据您的答案更新问题。 :) – tychoD

+0

谢谢,这确实回答了我的问题。 :D – tychoD

+0

我必须在dealloc()中清除所有的@properties吗? –

viewDidUnload现已被弃用,不再由系统调用(截至iOS 6)。它从来没有像苹果希望的那么有用,而且比它值得的更麻烦。这与ARC无关。

dealloc通常在ARC下不需要,但在需要非ARC资源管理的情况下仍然是必需的。例如,如果您需要使用free()或以其他方式发布资源。这也是一个以观察员或代表身份去除自己的好地方。但是很多课程现在不需要dealloc