UIView的生命周期
UIView对象一般都是由alloc和init方法创建的,由UIViewController进行维护和管理。一般需要完成的任务有:创建视图,显示视图,隐藏视图和释放视图。
一般视图不会在程序运行时立刻创建并载入,只有当应用需要这个视图的时候才会创建,这种延迟创建视图的方法能够提高内存的使用效率。同样,在需要这个视图之前,系统会检查是不是已经载入过这个视图,如果是,直接返回创建过的view,如果没有,则开始创建过程
- (void)loadView
载入视图过程中执行代码
- (void)viewDidLoad
视图载入完成需要执行的代码
- (void)viewDidUnload
卸载视图代码
一个视图切换到另一个视图的时候,之前那个视图并不会被清除,还会留在内存中等待系统调用,所以一个视图在使用到卸载过程中虽然可能多次出现,但是只会载入一次,也就是调用一次loadView和viewDidLoad方法。
在IOS6以前,在系统接收到Memory Warning时,会调用viewDidUnload这个方法,对视图进行卸载清空。但是IOS6以后这个方法已经不再被使用了,文档里是这么描述的
这里给出的解释是,视图不再在低内存的情况下被清除了。苹果公司WWDC2012对这个方法的告别陈述
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。
具体为什么不需要清空view呢,下面解释了原因(摘自唐巧的《再见,viewDidUnload方法》)
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: 方法重建。
所以苹果才会说现在会卸载那些真正占内存的独立内容,卸载UIView对象已经并不重要了。
另外,在每次视图显示和隐藏的过程中还会调用一些方法
- (void)viewWillAppear:(BOOL)animated
- (void)viewDidAppear:(BOOL)animated
- (void)viewWillDisappear:(BOOL)animated
- (void)viewDidDisappear:(BOOL)animated
写入在每次显示视图和隐藏视图时的代码块。
重要的是:视图控制对象和视图是两个独立的对象,Controller要借助View才能和用户进行交互,可以把视图看成一种可再生资源,可以创建,卸载(从前),可以显示,隐藏。