理一理UIViewController的东东

欢迎关注”iOS开发之道”的微博和微信帐号,一起交流学习。 微博:iOS开发之道 微信:ioszhidao

image


  UIViewController有什么好讲的呢?我本也以为如此,不过最近我们组面试了一些iOS候选人,发现还有不少人对每天都要见面的UIViewController懵懵懂懂的。
问题:
1.loadView, viewDidLoad, viewWillAppear的调用顺序?
2.viewDidLoad会在什么时候调用?会调用几次?
3.viewDidUnload会在什么时候调用?iOS6上怎么处理内存警告?
4.init方法会加载xib文件吗?
5.能把controller1.view添加到controller2.view上面吗?怎么添加?
  如果你能够回答完上述所有问题,可以不用往下看了:)

UIViewController是MVC中的Controller,负责管理每个窗口界面的视图和数据。
其主要方法及描述如下:
1.init
初始化

//从xib中加载会调用此方法,如果只是init,也会调用此方法从main bundle中加载与当前ViewController同名的xib文件
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil;    
//从storyboard中加载时会调用该方法
- (id)initWithCoder:(NSCoder *)aDecoder  

2.loadView
从xib或者storyboard中加载view,也可以重载loadView初始化view。
3.viewDidLoad
在loadView后调用,可在此进行一些初始化操作。

在iOS 6以前内存警告释放view后,会重新loadView,调用viewDidLoad。注意:这里只是UIViewController自己加载view并初始化层次结构,位置后。最终view的大小会在view添加到屏幕上面后重新计算,在viewWillAppear中的view.bounds才是最终的大小。比如,UIViewController被添加到UINavigationController时,其view的高度可能(请思考为什么是可能?)需要减去navigationBar的高度,但是这里还没有进行此操作。

4, viewDidUnload
view释放后调用此方法, 此时view=nil。比如内存警告会导致view释放。aViewController.view = nil会触发viewDidUnload吗?写个代码测试一下吧。等等…,如果你不再支持iOS 5,幸福的孩子,忘掉viewDidUnload吧。
5, viewWillAppear
view即将显示(添加到当前window的view hierarchy 结构)。此时view.bounds已经被重新计算为合适的结果了。如果你需要根据view的高度设置某些控件的高度,这里可以开始动手了…
6, viewDidAppear
整个view已经添加到屏幕上面,用户可以看见了。
7, viewWillDisappear, viewDidDisappear与上面两个相反。
8, viewWillLayoutSubviews
在layoutSubviews方法调用后执行,当view.bounds变化时,会触发该方法重新计算布局。
9, viewDidLayoutSubviews
布局重新计算后
10, didReceiveMemoryWarning
程序收到内存警告时,调用此方法,默认会释放self.view,如果其没有superview。

注意iOS 6后,收到内存警告后,view不会被释放,viewDidUnload也不会被调用。系统会释放view中包含的一些内容,具体自己debug一下?也可以飘过不用关心。在didReceiveMemoryWarning你可以释放一些可以重生的业务数据。

几个流程:
1.初始化UIViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil;
- loadView
- viewDidLoad

2.显示UIViewController - viewWillAppear
- viewWillLayoutSubviews
- viewDidLayoutSubviews
- viewDidAppear

3.收到内存警告
- didReceiveMemoryWarning
- viewDidUnload

ViewController的包含关系
在iOS 5之前,除了系统提供的UINavigationController, UITabBarController, UISplitViewController等几个Container ViewController,基于UIViewController派生的自定义ViewController是不能管理其它子ViewController的。

//这样使用是错误的,childViewController.view的确被加入到了self.view中,但是childViewController的viewWillAppear, viewWillDisappear以及内存警告等消息都没有办法收到,这些消息是以UIViewController为层次结构下发的,而不是UIView,所以当前ViewController不知道其view的一个subview有另外一个childViewController。
[self.view addSubview:childViewController.view];  

在iOS 5后,系统已经支持parentViewController, childViewController的概念了,可以按照下面方式实现:
1.Add a Child UIViewController

//child view's frame可以按照需求设置
childViewController.view.frame = self.view.bounds;   
[self addChildViewController:childViewController ]; 
[self.view addSubview:childViewController.view];
//主要是通知child view controller
[childViewController didMoveToParentViewController:self]; 

2.Remove a Child UIViewController

[childViewController willMoveToParentViewController:nil];  
[childViewController.view removeFromSuperview];
[childViewController removeFromParentViewController]; 

欢迎关注”iOS开发之道”的微博和微信帐号,一起交流学习。 微博:iOS开发之道 微信:ioszhidao

image

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值