您的位置:首页 > 产品设计 > UI/UE

UIViewController生命周期方法执行顺序

2013-11-25 11:33 274 查看

剖析UIviewController生命周期方法

面试必问问题:一是内存管理,二是viewcontroller的生命周期方法,三是tableview的复用,四是异步同步网络请求,五是多线程,六是数据存储。


UIviewController的生命周期方法调用顺序

假设现在有一个 AViewController(简称Avc) 和
BViewController (简称Bvc)   

通过navigationController的push实现 Avc 到 Bvc的跳转,那么让我们来看下Avc 和 Bvc生命周期的方法是怎样一个执行顺序。

下面就是正确的顺序

2013-11-25 10:32:43.937 TestJumpABC[647:a0b] A viewDidLoad
2013-11-25 10:32:43.938 TestJumpABC[647:a0b] A viewWillAppear
2013-11-25 10:32:43.962 TestJumpABC[647:a0b] A viewDidAppear
2013-11-25 10:32:45.972 TestJumpABC[647:a0b] B viewDidLoad
2013-11-25 10:32:45.972 TestJumpABC[647:a0b] A viewWillDisappear
2013-11-25 10:32:45.975 TestJumpABC[647:a0b] B viewWillAppear
2013-11-25 10:32:45.978 TestJumpABC[647:a0b] A viewDidDisappear
2013-11-25 10:32:45.978 TestJumpABC[647:a0b] B viewDidAppear

那么我们从Bvc 返回到 Avc呢?执行顺序又是怎么样的呢?

2013-11-25 10:34:15.719 TestJumpABC[647:a0b] B viewWillDisappear
2013-11-25 10:34:15.721 TestJumpABC[647:a0b] A viewWillAppear
2013-11-25 10:34:16.226 TestJumpABC[647:a0b] B viewDidDisappear
2013-11-25 10:34:16.227 TestJumpABC[647:a0b] A viewDidAppear


现在终于清楚是怎么回事了。


loadview到底是什么时候执行?

先来看看官方文档吧

loadView
Creates the view that the controller manages.

- (void)loadView
Discussion
You should never call this method directly. The view controller calls this method when its view property is requested but is currently nil. This method loads or creates a view and assigns it to the view property.

If the view controller has an associated nib file, this method loads the view from the nib file. A view controller has an associated nib file if the nibName property returns a non-nil value, which occurs if the view controller was instantiated from a storyboard, if you explicitly assigned it a nib file using the initWithNibName:bundle: method, or if iOS finds a nib file in the app bundle with a name based on the view controller’s class name. If the view controller does not have an associated nib file, this method creates a plain UIView object instead.

If you use Interface Builder to create your views and initialize the view controller, you must not override this method.

You can override this method in order to create your views manually. If you choose to do so, assign the root view of your view hierarchy to the view property. The views you create should be unique instances and should not be shared with any other view controller object. Your custom implementation of this method should not call super.

If you want to perform any additional initialization of your views, do so in the viewDidLoad method.

Availability
Available in iOS 2.0 and later.
See Also
@property view
@property nibName
– viewDidLoad
Related Sample Code
iPhoneCoreDataRecipes
Declared In
UIViewController.h
其实这个方法网上已经有很多人做过研究了,并且也试验过,确实可行,参考博客: loadView学习总结

当view需要被展示而它却是nil时,viewController会调用loadview方法。不要程序员直接代码调用该方法。
如果手工维护views,必须重载重写该方法
如果使用IB维护views,必须不能重载重写该方法}

开始时对上述感觉很迷惑,我想这不是他想表达的本意

self.view = [[[NSBundle mainBundle] loadNibNamed:@"OneNibName" owner:self options:nil] lastObject];
我想在loadView中这样用也是可以的,我是手工维护view,但view是从IB中加载的。

还有一点,和loadView一个界别的还有一个方法initWithNibName,这个方法是在controller中的类在IB中创建,但是通过Xcode实例化controller的时候用的.(建立一个viewBase的模板工程,然后打开MainWindow.xib,删除其中的viewController,然后回到viewController.m中,把第一个方法initWithNibName注释取消掉,然后加入一条你喜欢的打印语句,试试是不是这样的)

“一般的用法是在loadView/initWithNibName里面创建基本的界面,然后在viewDidLoad里读入数据,然后根据数据再将各view设置为正确的状态。”这句话是否准确,我觉得loadview是用来实例化一个有效的view,而initWithNibName是从xib文件实例化一个viewcontroller的。
这也是我个人的见解,如果有不正确的地方,还希望大牛们多多指点出来啊。


viewdidload什么时候执行?

 Called after the view has been loaded. For view controllers created in code, this is after -loadView. For view controllers
unarchived from a nib, this is after the view is set.
就是当一个controller重新loadView完的时候执行。什么意思? 举例,一般Avc跳转到Bvc,正常情况下Bvc返回Avc的时候是不调用A的viewdidload的,是因为Avc这个对象还存在内存中,它的view以及subviews也都还存在内存中,所以系统没有执行A的loadview方法,也就没有执行A的viewdidload方法。那么有时候情况是这样的,Avc跳转到了Bvc,这时候出现了设备内存不足的警告,
也就是viewController会收到didReceiveMemoryWarning的消息。系统会默认释放掉不在当前使用的view
hierarchy的视图,也就是Avc的view及其subview被释放了。那么Bvc返回到Avc的时候就,Avc首先要调用loadview去创建一个有效的view,在调用viewdidload来进行其他subview的初始化。 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息