UIViewController中的loadView、viewD
我们创建的controller中默认有viewDidload方法,在创建自定义UI时也总是在这个方法中进行,why?与其相关的loadView以及viewDidUnload方法又是在什么时候调用?
-
loadView
通过调用栈及私有方法重写可以了解loadView方法的调用过程大致是:[UIViewController View]->[UIViewController loadViewIfRequired]->[UIViewController loadView];
函数调用栈图由此可以知道loadView的调用时机:
当访问UIViewController的view时会调用view的get方法,进而调用loadView。
那loadView有什么用呢?查看UIViewController的view属性:
@property(null_resettable, nonatomic,strong) UIView *view; // The getter first invokes [self loadView] if the view hasn't been set yet. Subclasses must call super if they override the setter or getter.
可知loadView的作用:创建UIViewController的view。
默认实现[super loadView]做了些什么呢? - 查找UIViewController相关的xib文件创建view
a.有指定xib文件加载指定xib;
b.没有指定xib文件则加载同名xib;
c.没有找到相关xib则创建空白view。
// applicationFrame的值是:{{x = 0, y = 20}
self.view = [[[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame] autorelease];
-
viewDidLoad
viewDidLoad什么时候会被调用呢?见名思意,view在已经载入的时候调用?来看官方文档的解释:
Called after the controller'��s view is loaded into memory.
This method is called after the view controller has loaded its view hierarchy into memory. This method is called regardless of whether the view hierarchy was loaded from a nib file or created programmatically in the loadView method. You usually override this method to perform additional initialization on views that were loaded from nib files.
即viewDidLoad方法在view加载到内存中后就会调用,由上可知是在loadView方法调用后的某个时间,此时view在内存中还没有在屏幕上渲染,因此该方法一定早于viewWillAppear方法。一般情况下该方法只会调用一次,但是当出现内存警告,view被unload从内存中清除后会重新调用该方法,或者不断的创建controller,然后push it again and again。
作用:做一些初始化工作(添加子视图等),因为此时view已经加入内存中可以拿到self.view。 -
viewDidUnLoad(iOS6后已弃用)
官方文档:
Called after the view controller's view is released and set to nil. For example, a memory warning which causes the view to be purged. Not invoked as a result of -dealloc.
可知当controller的view释放后就会调用viewDidUnload方法,事实上当应用程序占用内存过多,就会向UIViewController发出didReceiveMemoryWarning消息,在didReceiveMemoryWarning中只要controller的view不在view层级,即view的superview为nil的时候,就会将view释放,并且调用viewDidUnload方法。 -
三个方法的关系
- 系统第一次调用[UIViewController View]获取view时view为nil,调用
loadView为controller创建view;
2)view创建完毕加载到内存后会调用viewDidLoad方法,在viewDidLoad方法进行
界面UI的初始化;
3)当发生内存警告,controller的view可能被释放,view设置为nil,并调用
viewDidUnload方法;
4)当再次访问controller的view时,view已在3)中被置为nil,因此会调用
loadView重新创建view;
5)重复2).
- view的载入过程
view载入的一般过程如下图所示:
从UIWindow的makeKeyAndVisible开始->调用UIWindow私有方法addRootViewControllerViewIfPossible->UIWindow调用get方法获取root view controlller的view
->get方法中调用loadViewIfRequired方法->调用loadView方法->调用私有方法j加载view->调用view controller内部window方法,如preferedInterfaceOrientation、supportedInterfaceOrientations等(多次调用)
->调用viewDidLoad->调用私有方法_viewWillAppear(calls viewWillAppear on view controller)->willMoveToWindow->willMoveToSuperview-> _didMoveFromWindow:toWindow
->调用自动布局方法
->调用viewDidAppear:此时视图被渲染出来了。
PS: I am xinghun who is on the road.