iOS开发UI篇-UIView的生命周期

作者: willphonez | 来源:发表于2016-07-20 17:26 被阅读4013次

    一、 大体流程:


    • (loadView/nib)文件来加载view到内存-->viewDidLoad函数进一步初始化这些view-->内存不足时, 调用viewDidUnload函数释放views-->当需要使用view时又回到第一步
    • loadView:永远不要主导调用这个函数。viewController 会在view的property被请求并且当前view值为nil时调用这个函数。如果你手动创建view, 你应该重载这个函数,切不要在重载的时候调用[super loadView]。
    • viewDidload:这个函数的作用主要是让你可以进一步的初始化你的views。viewDidLoad通常负责的是view及其子view被加载进内存之后的数据初始化的工作,即视图的数据部分的初始化
    • viewDidUnLoad:这个函数时viewDidLoad的对立函数。在程序内存欠缺时,这个函数被controller调用,来释放他的view以及view相关的对象。由于controller通常保存着view以及相关的object的引用,所以你必须使用这个函数来放弃这些对象的所有权以便内存回收,但不要释放那些难以重建的数据
    • viewWillAppear:视图即将可见时调用,默认情况下不执行任何操作。
    • viewWillLayoutSubViews:视图在显示之前会布局子控件(将要布局子控件的时候调用)
    • viewDidLayoutSubViews:已经布局完子控件的时候调用
    • viewDidAppear:视图已完全过渡到屏幕上时调用
    • viewWillDisappear:视图被驳回时调用,覆盖或以其他方式隐藏,默认情况下不执行任何操作
    • viewDidDisappear:视图被驳回后调用,覆盖或以其他方式隐藏。默认情况下不执行任何操作
    • didReceiveMemoryWarning:当程序内存过度时,系统会调用该方法

    二、Controller和View的生命周期


    • 这里指的View是指Controller的View。它作为Controler的属性,生命周期在Controller的生命周期内。就是说你的Controller不能在view释放前就释放了。
    • 当你alloc并init了一个ViewController时,这个ViewController应该是还没有创建view的。
    • ViewController的view是使用了lazyInit方式创建,就是说你调用的view属性的getter:[self view]。在getter里会先判断view是否创建,如果没有创建,那么会调用loadView来创建view。
    • loadView完成时会继续调用viewDidLoad。loadView和viewDidLoad的一个区别就是:loadView时还没有view。而viewDidLoad时view以及创建好了。
    • 当view被添加其他view中之前时,会调用viewWillAppear,而view在显示之前会先调用viewWillLayoutSubViews以及viewDidLayoutSubViews来布局子控件,而之后才会调用viewDidAppear。
    • 当view从其他view中移出之前时,会调用viewWillDisAppear,而之后会调用viewDidDisappear。
    • 当view不在使用,而且是disappeared,受到内存警告时,那么viewController会将view释放并将其指向nil。

    加载View的流程
    1.先去判断当前控制器是不是从StoryBoard当中加载的,如果是,那么它就会从StoryBoard当中加载控制器的View.
    2.如果不是从StoryBoard当中加载的, 那么它还会判断是不是从Xib当中创建的控制器.如果是,那么它就会从xib加载控制器的View.
    * 加载Xib的时候会先看看有没有和控制器同名的Xib,有的话就加载;
    * 如果没有的话就会查找下有没有控制器的名称去掉controller的xib,有的话就去加载.
    3.如果也不是从Xib加载的控制器.那么它就会创建一个空的UIView.设为当前控制器的View.

    三、代码组织(如何设计良好的viewController)


    ViewController生命周期中有那么多函数,一个重要问题就是什么代码该写在什么地方

    • 1、init里不要出现创建view的代码。良好的设计,在init里应该只有相关数据的初始化,而且这些数据都是比较关键的数据。init里不要掉self.view,否则会导致viewcontroller创建view。(因为view是lazyinit的)。
    • 2、loadView中只初始化view,一般用于创建比较关键的view如tableViewController的tabView,UINavigationController的navgationBar,不可掉用view的getter(在掉super loadView前),最好也不要初始化一些非关键的view。如果你是从nib文件中创建的viewController在这里一定要首先调用super的loadView方法,但建议不要重载这个方法。
    • 3、viewDidLoad 这时候view已经有了,最适合创建一些附加的view和控件了。
    • 4、viewWillAppear 这个一般在view被添加到superview之前,切换动画之前调用。在这里可以进行一些显示前的处理。比如键盘弹出,一些特殊的过程动画(比如状态条和navigationbar颜色)。
    • 5、viewWillLayoutSubViews 一般用于显示前,对子控件进行布局
    • 6、viewWillLayoutSubViews子控件布局完成,可以在这方法里面对子控件进行一些初始化操作.
    • 7、viewDidAppear 一般用于显示后,在切换动画后,如果有需要的操作,可以在这里加入相关代码。
    • 8、viewDidUnload 这时候viewController的view已经是nil了。由于这一般发生在内存警告时,所以在这里你应该将那些不在显示的view释放了。比如你在viewcontroller的view上加了一个label,而且这个label是viewcontroller的属性,那么你要把这个属性设置成nil,以免占用不必要的内存,而这个label在viewDidLoad时会重新创建。
    • 9、接下来看看ViewController中的view是如何被卸载的:当系统发出内存警告时,会调用didReceiveMemoeryWarning方法,如果当前有能被释放的view,系统会调用viewWillUnload方法来释放view,完成后调用viewDidUnload方法,至此,view就被卸载了。此时原本指向view的变量要被置为nil,具体操作是在viewDidUnload方法中调用self.myButton = nil;
    • 小结一下:loadViewviewDidLoad的区别就是,loadView时view还没有生成,viewDidLoad时,view已经生成了,loadView只会被调用一次,而viewDidLoad可能会被调用多次(View可能会被多次加载),当view被添加到其他view中之前,会调用viewWillAppear,之后会调用viewDidAppear。当view从其他view中移除之前,调用viewWillDisAppear,移除之后会调用viewDidDisappear。当view不再使用时,受到内存警告时,ViewController会将view释放并将其指向为nil。

    ViewController的生命周期中各方法执行流程如下:init—>loadView—>viewDidLoad—>viewWillAppear—>viewWillLayoutSubViews—>viewDidLayoutSubViews—>viewDidAppear—>viewWillDisappear—>viewDidDisappear—>viewWillUnload->viewDidUnload—>dealloc

    相关文章

      网友评论

      本文标题:iOS开发UI篇-UIView的生命周期

      本文链接:https://www.haomeiwen.com/subject/mmivjttx.html