最近项目上比较闲,想起来啥就整理点啥,平时没怎么用没怎么深究的知识点还是要抠明白的,来吧:浅析loadView
学习苹果的东西,提倡先看官方文档,完了再结合网络搜索其他人的见解分析,这样不至于跟着别人的思路走,万一你百度出来的仁兄自己分析的偏了,那你就跟着跑偏了。。。。。
官方文档来一波:
Creates the view that the controller manages.
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.
---------翻译分割线----------
当控制器的view为nil时,会调用这个方法,这个方法会创建一个view给控制器.
如果控制器从xib加载控制的view,则你可以调用此方法来加载xib--> initWithNibName:bundle: 或者不调用此方法,控制器会根据有没有一个xib名字跟控制器类名一样的,如果一样就加载这个跟控制器名字一样的xib文件作为控制的view.如果没有xib来初始化控制器的view的话,则这个方法loadview会创建一个空白的view给控制器.
如果用storyboard初始化控制器,就不用调用loadview方法了.
如果重写这个方法给控制器创建view则这个view必须是一个单例,而且不能被其他的控制器使用.并且不可以调用super
如果想初始化自定义的view,则在viewdidload中初始化即可.
然后咱们自己写写代码验证:
从输出顺序可见loadView是在viewDidLoad之前执行的,用这俩方法的时候 注意顺序,用的不慎会出现覆盖赋值的问题。
接着分析:
跟第一张图片的区别是去掉了[super loadView]调用,这是走了两遍loadView和viewDidLoad:
- loadView和viewDidLoad的区别就是,调用loadView时view还没有生成,调用viewDidLoad时,view已经生成了.
- 当调用loadview时,view为空, -> 调用viewdidload控制器仍然没有自己的view,此时再次调用loadview方法让控制器生成一个黑色的view.
- 注意点: 此时如果调用了loadview当时没有给viewController指定一个view的话,不能在viewdidload方法中用self.view = 某个view,此时如果调用view的set或者get方法都会使程序进入无限死循环中.
然后我们在viewDidLoad里面调用一下self.view,看看效果,程序进入了死循环状态:
原因: 调用了self.view就相当于调用了loadview,由于重写loadview的方法时并没有给控制器的view指定一个view,所以会一直死循环下去...
解决办法之一就是在loadview方法中给self.view指定一个view,看代码:
这么处理之后死循环问题解决了 ,调用loadview方法,要给控制器指定view.否则在viewdidload方法中调用self.view(view的set或者get方法)都会使程序进入死循环.当然要是写了[super loadView];那就没问题。
再来一段代码:
如果在loadview与viewdidload中都给控制器指定了view,那么从调用方法的顺序上看可以得到结果:最后被调用的viewdidload方法中的view会覆盖掉loadview中给控制器设置的view.
结论:
不建议使用loadview,可以根据自己的需要在storyboard或者viewdidload中创建自己需要的view给控制器.
附加一张生命周期图解: