由于工作需要开始接触IOS开发,而ViewController是我们最常接触的,弄清ViewController的实现细节,才能灵活的进行IOS开发。这段时间看了许多关于ViewController的资料,现在整理如下,其中很多是参考网友资料。
ViewController属于MVC模式当中的C,他是View的Controller, 扮演者一个大管家的身份,管理着程序中的众多视图,用于管理内部各个View的加载显示和卸载以及负责与其他ViewController的通信和协调。
ViewController主要分为两类:
一类是contentViewController,如:UIViewController,UITableViewController等,以及自定义继承自UIViewController的ViewController。另一类是containerViewController,如:UINavigationViewController和UITabBarController等,UINavigationController是以Stack的形式来存储和管理ViewController,UITabBarController是以Array的形式来管理ViewController
ViewController的生命周期:
init—>loadView—>viewDidLoad—>viewWillApper—>viewWillLayoutSubViews—>viewDidLayoutSubViews—>viewDidApper—>viewWillDisapper—>viewDidDisapper—>(当内存吃紧调用)didReceiveMemoryWarning—>viewWillUnload—>viewDidUnload(ios6.0已经舍弃)—>dealloc。
当访问view属性时,如果view存在,则直接加载。如果不存在,则调用loadView方法,创建view如下图所示。
View的创建方式:
1)storyboard创建VC
IOS 5.0的新特性,也是现在最常用的方法,简单方便(不再累述)。
2)xib创建VC
xib其实最终是会把我们的设置保存成一个数据集,当需要初始化构建VC的时候,回去读取记录的数据集,然后帮我们动态的创建VC,因此可以想象它在初始化时会先去找看是否实现initWithCoder方法,如果该类实现了该方法,就直接调用initWithCoder方法创建对象,如果没有实现的话就调用init方法。调用完初始化方法以后紧接着会调用awakeFromNib方法,在这个方法里面我们可以做进一步的初始化操作。利用xib方式创建VC时,如果不指定XIB文件,则初始化的时候默认加载与viewController同名的xib文件。
示例代码:
///< 指定xib文件创建
RootViewController *rootViewController = [[RootViewController alloc] initWithNibName: @"RootViewController" bundle:nil];
///< 不指定XIB文件名
RootViewController *rootViewController = [[RootViewController alloc] init];
3)代码创建VC使用代码创建时,我们根据需要手动的创建VC中的数据,如果自己定制VC时,还需要在init中调用[super init]。
示例代码:
///< 代码创建VC
RootViewController *rootViewController = [[RootViewController alloc] init];
rootViewController.view.backgroundColor = [UIColor redColor];
注意:
避免在viewDidLoad中调用还没有初始化的view时容易出现死循环。在viewDidLoad调用self.view时候,假如视图的值还是为nil,那么会调用loadView方法,加载完成后又调用viewDidLoad方法,这样的话就一直循环。
ViewController中的view卸载:
当系统发出内存警告时,会调用didReceiveMemoeryWarning方法,如果当前有能被释放的view,在ios6.0之前会调用viewWillUnload方法来释放view,完成后调用viewDidUnload方法,此时原本指向view的变量要被置为nil,具体操作是在viewDidUnload方法中调用。Ios6.0以及之后直接在didReceiveMemoeryWarning方法中进行处理。
关于viewDidUnload在发生内存警告的时候如果本视图不是当前屏幕上正在显示的视图的话,viewDidUnload将会被执行,所有子视图将被销毁释放内存。 因此当这个视图再次显示在屏幕上的时候,viewDidLoad 再次被调用,以构造视图。