准备知识(来自网易博友:烟花细雨):
1、按照结构可以把ViewController分为2类:
1)主要是用于显示内容的ViewController,这种ViewController主要是用于为用户展示内容,并且与用户交互,比如UITableViewCOntroller,UIVewController
2)永固控制和显示其他ViewController的ViewController,这种ViewController一般都是一个ViewCOntroller的容器。比如UINavigationController,UITableViewCOntroller。他们都有一个属性ViewCOntroller。其中UINavigationController表示一种stack结构,push一个ViewController或者pop一个ViewController。因此后一个ViewCOntroller就会依赖于前一个ViewController。而UITableBarCOntroller是一个Array结构,各个ViewController是并列的。第一种ViewCOntroller会经常被继承,用来显示不同的数据给用户,第二种比较少,除非有需要自定义它。
2、当view被添加到其他view之前时,会调用viewWillAppear,而后会调用viewDidAppear,
当view被从其他view移除是时,会调用viewWillDisAppear,而后会调用viewDidDisAppear
当view不在被使用时,而且是disAppear,收到内存警告时,viewController会将view释放掉并指向nil
3、由于viewController家在view时,会自动将一些view对象指向其对应的IBOutlet变量,所以当view被卸载时我们必须在viewDidUnload时将这些变量释放掉,ViewCOntroller不会自动做这些事情,具体的是将ViewController的属性设置为空即可。
ViewController加载过程
步骤一:
默认的执行顺序是:先寻找有关Nib文件的信息,然后执行init初始化方法进行Controller的实例化,顺序如下:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self =[superinitWithNibName:nibNameOrNilbundle:nibBundleOrNil];
if (self) {
NSLog(@"initWithNibName");
}
returnself;
}
- (id)init
{
self =[superinit];
if (self) {
NSLog(@"init");
}
returnself;
}
函数用途:不要在init、initWithNibName方法内创建view的代码。良好的设计,应该是只有相关数据的初始化,而且这些数据都是比较关键的数据。init里面不要掉self.view
,否则就会导致Controller创建View(因为View是lazyload的)
步骤二
当View需要被展示时,但是View却为nil,ViewController会自动调用该方法。如果不用Nib文件,需要重载该方法实现自定义布局。
- (void)loadView;
用途:只初始化View,一般用于创建的view如UITableView的tableView,NavigationController的navigationBar,最好也不要初始化一些非关键的View
思考:对于View的自定义应该在该函数写(View还未出现)。
步骤三
当View被加载时,对于用代码实现的ViewController,ViewDidLoad的方法在loadView之后加载,当View的属性被设置是也会调用该方法
- (void)viewDidLoad;
用途:此时View已经有了,适合创建一个子View和控件。ViewDidLoad可能会调用多次(viewCOntroller可能会多次载入view)
思考:你可以重载该函数进一步定制View(View还未出现),或者使用- (BOOL)isViewLoaded来判断View是否被加载完成
步骤四:
- (void)viewWillAppear:(BOOL)animated
{
NSLog(@"viewWillAppear");
}
视图将要出现,默认不执行任何操作
用途:此时view被添加到superview之前,切换动画之前调用。可以进行显示前的处理,比如键盘弹出,一些特殊动画(状态条、Navigationbar的颜色)
思考:可以用来更新准备显示视图的信息
步骤五:
- (void)viewWillLayoutSubviews
- (void)viewDidLayoutSubviews
步骤六:
-(void)viewDidAppear:(BOOL)animated;
View完全过渡到屏幕,默认不执行任何操作
用途:一般是显示后,在切换动画后,有其他的操作写在这个函数里面
思考1:可以用来触发视图完全显示在屏幕上之后的行为,例如任何动画的操作
思考2:和viewDidLoad的区别,viewDidLoad只是在第一次生成并加载View的时候调用,以后都不会用到,但是viewDidAppear是每次视图出现都被调用的。
思考3:整个加载顺序:initWithNibName->init->loadView->viewDidLoad->viewWillAppear->
viewWillLayoutSubviews->viewDidLayoutSubviews->viewDidAppear
ViewController卸载过程:
步骤一:
-(void)viewWillDisappear:(BOOL)animated;
View释放前调用该函数
步骤二:
-(void)viewDidDisappear:(BOOL)animated;
View释放时调用该函数
步骤三:
-(void)viewWillUnload;
-(void)viewDidUnload;
系统内存不足时调用该方法
用途:调用viewDidUnload的时候,Viewcontroller的view已经是nil。由于一般发生内存警告,所以在这里主要是释放不再显示的view。比如viewController的view加了一个button,而且这个button是viewcontroller的属性,那么你就把这个button属性设为nil,以免占用不必要的内存。这个button会在viewDidLoad的时候重新被创建。
思考1:可以使用ViewDidUnload函数释放视图所拥有的所有数据,当然贼额数据宅视图重新被载入内存时能够很容易创建。
思考2:收到内存警告,不可见的Controller的View被释放并被设置为nil
步骤四:
-(void)didReceiveMemoryWarning;
内存紧张时调用,释放ViewDidUnLoad函数中没有被释放的数据
步骤五:
-(void)dealloc;
释放视图对象的引用和viewController所需的数据结构
思考:当收到内存警告时,内存中的所有UIViewCOntroller都会收到didEceive
MemoryWarning调用信息,目的是讲不可见的UIViewController中的View释放掉,但是不调用dealloc方法,所以当该UIViewCOntroller在此显示时又要省城一次,调用函数顺序如下:
Loadview->viewDidLoad->viewWillAppear(内存警告被释放的view再一次生成)