当系统遭遇内存警告的时候,会调用VC的下述函数,在该函数内存,我们可以释放一些能够再次被创建的资源,比如维持的从网络或者数据库来的数据等等。 ~~~
(void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } ~~~
视图管理流程
先来看一张比较大的图,这是apple目前提供的和View控制相关的一些函数的摘录(UIViewController中的函数).而这也是一个调用的时序关系图。VC的view还有其子View的创建使用,都在这个流程之中。
流程解释
创建根视图
当VC.view为空的时候,并且第一次调用vc.view的时候,会调用loadView函数来加载跟视图。
- (void) loadView
{
self.view = [UIViewnew];
}
在这个函数中你可以使用self.view = **来对根视图进行赋值,而且建议也是只在这里进行根视图的赋值操作。因为一旦根视图确定后,外部会对根视图进行一些布局了之类的操作,如果在使用过程中随意的更换根视图,上述的这些操作将很难重放。导致界面的一些异常。
初始化根视图上子视图
当调用了loadView加载了根视图之后,系统会触发VC的ViewDidLoad函数。这个使用self.view已经有值,可以在其上addSubView了。
在这里我们一般会做一些处理初始化子视图,并且addSubView之类的操作。注意布局的事情,就不要在这里做了,因为系统为我们提供了专门的函数来做这个事情。而且这个地方你拿到的self.view的frame信息是不准确的。比如刚才我们在loadView中没有对view进行布局初始化,给他设置一个frame。到了这个ViewDidLoad的地方的时候,你拿到的self.view.frame就是{0,0,0,0}。也就是说,你在这里进行布局的话,非常有可能是乱的。
- (void)viewDidLoad {
[superviewDidLoad];
_subView = [DZViewnew];
_subView.backgroundColor = [UIColor whiteColor];
[self.view addSubview:_subView];
}
布局
一般情况下,对于VC的根视图的操作是外部进行的,比如UINavigationController去push一个VC的时候,就会对vc.view.frame进行赋值,来控制VC的布局。而系统的这些试图控制器(导航了,之类的东西),都实现了CALayer的delegate,当vc的根视图的frame发生变化的时候会接受到通知
- layoutSublayersOfLayer:
系统的视图控制器会在这里面调用这两个函数来通知其当前的子VC去做布局的工作:
- viewWillLayoutSubviews
- viewDidLayoutSubviews
而这个子VC一般是我们创建的。在这两个函数里面我们去做布局的操作。这两个函数一个是在view本身的布局做完之前调用,一个是之后。无论哪个函数,这里面渠道的根视图的frame或者bounds信息都是准确的。
而且,如果在这两个函数里面进行相对布局操作的话,将会让VC的根视图拥有适配不同屏幕的能力,同时当调整根视图的frame的时候,整个视图的布局也能够作出相应的变化。
显示流程
- viewWillAppear:
– viewDidAppear:
- viewWillDisappear:
- viewDidDisappear:
从上述函数的字面意思理解:当视图被加载之后,要在window上显示出来,处于用户可见区域,或者离开用户可见区域的时候。系统将会调用VC相关函数来通知这种变化。
我们去看viewWillDisappear的文档:
This method is called in response to a view being removed from a view hierarchy. This method is called before the view is actually removed and before any animations are configured.
而上述显示流程能够被触发是依赖系统的这套机制的:
而现在系统集中默认的试图管理器UINavitionController,UITabBarController,还有present方式,都是可以保证会使用上述机制来触发响应的显示逻辑的。在这些函数里面,我们可以做一些和显示相关的业务逻辑了。
但是当你做业务逻辑的时候,一定要考虑这个函数在整个流程中的时序关系和他所代表的涵义。尤其是在每个视图管理器中的控制流程中,比如最开始提到的去获取self.navigationController为空的问题。
总结
关于ViewController的关键的流程,先视图管理这个。当然其还有其他的一些流程,要说完有点太复杂了。希望通过上述的两个例子,能够展示一下流程建模在理解框架和使用框架上的一些的裨益。能够使用这种思想来思考日常的编程问题。