我是一个负责iOS遗留代码的大型团队的一员,目标iOS环境为4.3及更高版本。我见过其他开发人员检查来自NSObject
但没有dealloc
方法的类。我还看到了不包含UIViewController
方法的viewDidUnload
个后代。当我询问这段代码时,通常的回答是“别担心,ARC现在负责处理。”
我理解当iOS遇到内存不足的情况时会调用viewDidUnload
,其目标是通过调用viewDidLoad
释放可以重新创建的对象来释放内存,而dealloc
是当对象的保留计数达到零时调用。对于UIViewController对象和后代,这可能意味着在dealloc
之前可能会或可能不会调用'viewDidUnload'。
所以这是我的问题:在iOS 6之前的iOS版本上使用ARC时,仍然需要dealloc
和viewDidUnload
方法吗?
如果答案是“是!”,那么我需要充分的理由和/或文件来进行论证。
期待您的回复。 (感谢Tommy帮助我收紧我的问题。)
答案 0 :(得分:14)
viewDidUnload
is deprecated。因此,无论ARC如何,您不仅不需要一个,而且不应该使用一个。陈述的理由是视图不再被低内存警告清除(大概是因为它们现在对总数的贡献太小而不值得响应性命中);如果部分理由是很多人认为他们可以在viewDidLoad
内释放viewDidUnload
中创建的所有资源,那么我就不会感到惊讶,仅此一项就可以防止泄密。这不是真的,因为viewDidUnload
是
仅在视图由于内存不足警告而卸载时调用。它不会在正常生命周期中调用。
如果需要管理资源,可以实现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无关。
dealloc
,但在需要非ARC资源管理的情况下仍然是必需的。例如,如果您需要使用free()
,或以其他方式释放资源。它也是一个将自己视为观察者或代表的好地方。但是现在很多课程都不需要dealloc
。