很多人误解了viewDidUnload
. 特别是,它不是. viewDidLoad
在大多数情况下,您的视图控制器将在不viewDidUnload
被调用的情况下被释放。出于这个原因,您永远不应该考虑在viewDidUnload
适当的平衡中为viewDidLoad
.
viewDidUnload
已被 Apple 弃用。反对使用它的最佳论据可能是它的标题(我已经包装了):
- (void)viewDidUnload NS_DEPRECATED_IOS(3_0,6_0); // Called after the view
// controller's view is released and set to nil. For example, a memory warning
// which causes the view to be purged. Not invoked as a result of -dealloc.`
那是什么viewDidUnload
?它背后的想法是视图正在从视图控制器后面卸载。这使您有机会分离任何指向它的指针并清除您可以轻松重建的任何信息。您的视图可能会被重新加载,此时您需要重建所有缓存。苹果是这样描述的:
当内存不足的情况发生并且不需要当前视图控制器的视图时,系统可能会选择从内存中删除这些视图。此方法在视图控制器的视图被释放后调用,这是您执行任何最终清理的机会。如果您的视图控制器存储了对视图或其子视图的单独引用,您应该使用此方法来释放这些引用。您还可以使用此方法删除对您为支持视图而创建但在视图消失后不再需要的任何对象的引用。您不应使用此方法发布用户数据或任何其他无法轻松重新创建的信息。
请记住,viewDidUnload
现在应该不需要将对对象的引用清零。如果您按照 Apple 的建议使用 ARC,则您的视图渠道正在将弱引用归零。没有你写,他们会自动被取消viewDidUnload
!
此外,清除缓存信息更适合didReceiveMemoryWarning
,因此您应该改为编写它:
您可以覆盖此方法以释放视图控制器使用的任何额外内存。如果这样做,则此方法的实现必须在某个时候调用超级实现以允许视图控制器释放其视图。如果您的视图控制器持有对视图层次结构中视图的引用,您应该在viewDidUnload
方法中释放这些引用。
一般来说,人们放入的东西viewDidUnload
最好用viewDidDisappear
or处理dealloc
。剩下的唯一事情就是在视图控制器仍然打开的情况下,在视图重新加载后的某个时间点需要时,viewDidUnload
清空任何可以在不丢失数据的情况下重建的缓存。(同样,这应该在 中处理didReceiveMemoryWarning
。)这些缓存应该是惰性构建的;当您的应用再次需要它们时,它会悄悄地重建它们。
那么你应该做什么viewDidUnload
呢?如果您使用的是 ARC:没有。甚至不要写它。事实上,自从写了这个答案以来,Apple 已经弃用了viewDidUnload
.
对于CGContextRelease
,CGContext
资源不是 Objective-C 对象。(你指出了这一点,但我想为后代重复。)因此,它不能被 ARC 自动释放。您有责任确保它像旧的手动保留释放 (MRR) 内存管理方案一样被释放和取消。
如果您将此代码放入 中viewDidUnload
,则不能保证它会被调用。它必须进去dealloc
。你也可以把它放进去viewDidUnload
,但是……</p>
所以:
- 没有必要也没有帮助。与视图层次结构相比,您的实例变量微不足道。
- 没有必要也没有帮助。与视图层次结构相比,您的属性微不足道(只要您的属性不是对视图层次结构的强引用)。
- 这将导致内存泄漏,
dealloc
通常在没有viewDidUnload
.
- 没有必要也没有帮助。见第 1 点和第 2 点。