控制器加载原理
最近补了一下控制器和UI的加载原理
这篇文章先聊一下控制器的加载原理和一些注意的点,有时候碰到问题,可以从这些点出发考虑。
控制器两种加载方式
xib和纯代码
xib的方式:
[[XHViewController alloc] initWithNibName:@"XHViewController" bundle:[NSBundle mainBundle]];
加载成功后,会调用awakeFromNib
纯代码的方式:
直接[[alloc] init];
两种方式,走会走initWithNibName,只是纯代码的方式下,参数为nil
loadView方法
截了一张图,看一下loadview方法的调用时机
1.1我们看到,viewDidLoad之前调用的是loadView
系统在loadView方法里,加载控制器所对应的view,如果重写loadView而什么都不做,那么这个控制器就没有view。于是我又在viewdidload里打印了一下view
1.2结果是什么呢??。。。。。
结果是crash了~~ 来看一下堆栈信息
1.3由此可见,无论load里是否成功创建了控制器的view,viewdidload都会走。并且我在viewdidload里引用self.view 此时又会调用loadView,loadView完了后又会走viewdidload,造成了死循环
结论:控制器的view是一个懒加载过程
生命周期
这里对生命周期这个问题的思考主要是两种情况下,“appear”相关方法的调用时机:控制器的push 和 pop操作时。假设现在有两个控制器Viewcontroller和XHViewController 当 ViewController Push 到 XHViewController时,方法的调用顺序:
1.4结论如上
接下来看一下从XHViewController Pop到ViewController
1.5可以得出结论:当前所在控制器先willDisappear --> 目标控制器 willAppear -->当前控制器 didDisappear --> 目标控制器didAppear
布局安全方式
在控制器中,建议在viewWillLayoutSubviews而不是viewDidLoad中做布局
在视图中,建议在layoutSubViews而不是initWithFrame中做布局
原因:layoutsubview是系统布局完成时调用的方法,在此方法中,所获取的视图frame是一定正确的。而viewdidload和initWithFrame中的视图大小,都可能不正确