再见,viewDidUnload方法

http://www.cocoachina.com/ios/20130520/6236.html

我在去年的一篇文章《iOS5中UIViewController的新方法》中介绍了iOS5引入的关于ViewController的新方法。但是现在如果运行该文章中的Sample代码的话,你会发现Log中不会再出现viewDidUnload方法被调用的记录。这是因为在iOS6中,viewDidUnload回调方法被Deprecated掉了。查看苹果的文档,可以看到如下的说明。

那么,原本在viewDidUnload中的代码应该怎么处理?在iOS6中,又应该怎么处理内存警告?带着这些问题,我查找了一些资料,在此分享给大家。

分析
在iOS4和iOS5系统中,当内存不足,应用收到Memory warning时,系统会自动调用当前没在界面上的ViewController的viewDidUnload方法。通常情况下,这些未显示在界面上的ViewController是UINavigationController Push栈中未在栈顶的ViewController,以及UITabBarViewController中未显示的子ViewController。这些View Controller都会在Memory Warning事件发生时,被系统自动调用viewDidUnload方法。

在iOS6中,由于viewDidUnload事件在iOS6下任何情况都不会被触发,所以苹果在文档中建议,应该将回收内存的相关操作移到另一个回调函数:didReceiveMemoryWarning 中。但是如果你仅仅是把以前写到viewDidUnload函数中的代码移动到didReceiveMemoryWarning函数中,那么你就错了。以下是一个 错误的示例代码 :

1.- (void)didReceiveMemoryWarning {
2.    [super didReceiveMemoryWarning];
3.    if([self isViewLoaded] && ![[self view] window]) {
4.        [self setView:nil];
5.    }
6.}

这篇文章解释了iOS6不推荐你将view置为nil的原因(链接打开需要FQ), 翻译过来如下:

1.UIView有一个CALayer的成员变量,CALayer是具体用于将自己画到屏幕上的。如下图所示:

2.CALayer是一个bitmap图象的容器类,当UIView调用自身的drawRect时,CALayer才会创建这个bitmap图象类。

3.具体占内存的其实是一个bitmap图象类,CALayer只占48bytes, UIView只占96bytes。而一个iPad的全屏UIView的bitmap类会占到12M的大小!

4.在iOS6时,当系统发出MemoryWarning时,系统会自动回收bitmap类。但是不回收UIView和CALayer类。这样即回收了大部分内存,又能在需要bitmap类时,通过调用UIView的drawRect: 方法重建。

内存优化
另外文章中还提到苹果的操作系统对此做的一个内存优化技巧,解释如下:

当一段内存被分配时,它会被标记成“In use“, 以防止被重复使用。当内存被释放时,这段内存会被标记成”Not in use”,这样,在有新的内存申请时,这块内存就可能被分配给其它变量。

CALayer包括的具体的bitmap内容的私有成员变量类型为CABackingStore, 当收到MemroyWarning时, CABackingStore类型的内存区会被标记成volatile类型(这里的volatile和 C以及Java语言的volatile不是一个意思),volatile表示,这块内存可能被再次被原变量重用。

这样,有了上面的优化后,当收到Memoy Warning时,虽然所有的CALayer所包含的bitmap内存都被标记成volatile了,但是只要这块内存没有再次被复用,那么当需要重建bitmap内存时,它就可以直接被复用,而避免了再次调用 UIView的 drawRect: 方法。

总结
所以,简单来说,对于iOS6,你不需要做任何以前viewDidUnload的事情,更不需要把以前viewDidUnload的代码移动到 didReceiveMemoryWarning方法中。

引用WWDC 2012 中的一段话来给viewDidUnload说再见:

The method viewWillUnload and viewDidUnload. We’re not going to call them anymore. I mean, there’s kind of a cost-benifit equation and analysis that we went through. In the early days, there was a real performance need for us to ensure that on memory warnings we unloaded views. There was all kinds of graphics and backing stores and so forth that would also get unloaded. We now unload those independently of the view, so it isn’t that big of a deal for us for those to be unloaded, and there were so many bugs where there would be pointers into。

时间: 2024-10-11 00:56:37

再见,viewDidUnload方法的相关文章

UIView的一些基本方法 init、loadView、viewDidLoad、viewDidUnload、dealloc

init方法 在init方法中实例化必要的对象(遵从LazyLoad思想) ‍init方法中初始化ViewController本身 loadView方法 当view需要被展示而它却是nil时,viewController会调用该方法.不要直接调用该方法. 如果手工维护views,必须重载重写该方法 如果使用IB维护views,必须不能重载重写该方法 loadView和IB构建view viewDidLoad方法 重载重写该方法以进一步定制view 在iPhone OS 3.0及之后的版本中,还应

View的生命周期方法:loadView、viewDidLoad、viewDidUnload的关系

标题中所说的方法,都是UIViewController的方法,跟UIViewController的view属性的生命周期息息相关 loadView方法 1. 什么时候被调用: 每次访问UIViewController的view(比如controller.view.self.view)而且view为nil,loadView方法就会被调用 2. 作用: loadView方法是用来负责创建UIViewController的view 3. 默认实现什么:(即[super loadView]里面做了什么事

loadView、viewDidLoad及viewDidUnload使用方法及概念

本文目录 一.loadView 二.viewDidLoad 三.viewDidUnload 四.三个方法的关系 标题中所说的3个方法,都是UIViewController的方法,跟UIViewController的view属性的生命周期息息相关.接下来我会一一阐述它们的作用以及它们之间的联系. 一.loadView 1.什么时候被调用? 每次访问UIViewController的view(比如controller.view.self.view)而且view为nil,loadView方法就会被调用

loadView、viewDidLoad及viewDidUnload的关系

一.loadView 1.什么时候被调用? 每次访问UIViewController的view(比如controller.view.self.view)而且view为nil,loadView方法就会被调用. 2.有什么作用? loadView方法是用来负责创建UIViewController的view 3.默认实现是怎样的? 默认实现即[super loadView]里面做了什么事情. 1> 它会先去查找与UIViewController相关联的xib文件,通过加载xib文件来创建UIViewC

loadView、viewDidLoad及viewDidUnload的关系(转)

原文:http://blog.csdn.net/q199109106q/article/details/8614044/ 标题中所说的3个方法,都是UIViewController的方法,跟UIViewController的view属性的生命周期息息相关.接下来我会一一阐述它们的作用以及它们之间的联系. loadView(VC的view是懒加载) 1.什么时候被调用? 每次访问UIViewController的view(比如controller.view.self.view)而且view为nil

loadView 与 viewDidLoad 和 didReceiveMemoryWarning与viewDidUnload 详解

首先试验下:viewController初始化 分两个支路:initWithNibName加载初始化 及 init 直接初始化: <1>调用initWithNibName加载一个xib界面文件来实现初始化viewController: 在 self.viewController = [[[ViewController alloc] initWithNibName:@"ViewController_iPhone"bundle:nil] autorelease]; xib界面文

UI基础篇—loadView、viewDidLoad及viewDidUnload的关系

一.loadView 1.什么时候被调用? 每次访问UIViewController的view(比如controller.view.self.view)而且view为nil,loadView方法就会被调用. 2.有什么作用? loadView方法是用来负责创建UIViewController的view 3.默认实现是怎样的? 默认实现即[super loadView]里面做了什么事情. 1> 它会先去查找与UIViewController相关联的xib文件,通过加载xib文件来创建UIViewC

【内存管理】:谁应该写在viewDidUnload里,谁应该写在dealloc里,arc之后viewDidUnload怎么用

viewDidUnload方法 当系统内存吃紧的时候会调用该方法(注:viewController没有被dealloc) 内存吃紧时,在iPhone OS 3.0之前didReceiveMemoryWarning是释放无用内存的唯一方式,但是OS 3.0及以后viewDidUnload方法是更好的方式 在该方法中将所有IBOutlet(无论是property还是实例变量)置为nil(系统release view时已经将其release掉了) 在该方法中释放其他与view有关的对象.其他在运行时创

长路漫漫,唯剑作伴--loadView、viewDidLoad及viewDidUnload的关系

一.loadView 什么时候被调用? 每次访问UIViewController的view(比如controller.view.self.view)而且view为nil,loadView方法就会被调用. 有什么作用? loadView方法是用来负责创建UIViewController的view 默认实现是怎样的? 它会先去查找与UIViewController相关联的xib文件,通过加载xib文件来创建UIViewController的view 如果在初始化UIViewController指定了