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后调用,可在此进行一些初始化操作。
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。
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];
问题:
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];