zoukankan      html  css  js  c++  java
  • UIViewController的生命周期

    生命周期

    我们建立一个简单的模型来测试生命周期:新建两个ViewController,一个是主视图控制器(main ViewController,以下简称mainVC),一个是副视图控制器(sub ViewController,以下简称subVC),在mainVC里点击一个Button,以modal方式切换至subVC,然后在subVC里点击另一个Button关闭subVC并返回mainVC。我们将这两个控制器的每个状态都打印出来,各个阶段的执行如下:

    case 1. 第一次运行app:

    main loadView

    main viewDidLoad

    main viewWillAppear

    main viewDidAppear

     

    case 2. 在mainVC里点击Button,以modal方式切换至subVC:

    sub loadView

    sub viewDidLoad

    main viewWillDisappear

    sub viewWillAppear

    sub viewDidAppear

    main viewDidDisappear

     

    case 3. 在subVC里点击Button关闭subVC并返回mainVC

    sub viewWillDisappear

    main viewWillAppear

    main viewDidAppear

    sub viewDidDisappear

    sub dealloc

     

    当一个视图控制器被创建,并在屏幕上显示的时候代码的执行顺序:

    step 1:alloc 创建对象,分配空间

    step 2:init (initWithNibName) 初始化对象

    step 3:loadView 从nib载入视图 ,通常这一步不需要去干涉。除非你没有使用xib文件创建视图

    step 4:viewDidLoad 载入完成,可以进行自定义数据以及动态创建其他控件

    step 5:viewWillAppear 视图将出现在屏幕之前,马上这个视图就会被展现在屏幕上了

    step 6:viewDidAppear 视图已在屏幕上渲染完成

     

    当一个视图控制器被移除屏幕并且销毁的时候的执行顺序:

    step 1:viewWillDisappear 视图将被从屏幕上移除之前执行

    step 2:viewDidDisappear 视图已经被从屏幕上移除,用户看不到这个视图了

    step 3:dealloc 视图被销毁

     

    这里需要说一下loadView与viewDidLoad的区别:当loadView时,还没有view;而viewDidLoad时,view已经创建好了。详细的加载循环:

    step 1:程序请求ViewController的view属性

    step 2:如果view在内存中,则直接加载;如果不存在,则调用loadView方法

    step 3:loadView方法执行如下方法:

    • 如果重载了这个方法,则必须创建必要的UIView并且将一个非nil值传给ViewController的view属性。
    • 如果没有重载这个方法,ViewController会默认使用自己的nibName和nibBundle属性尝试从nib文件加载view。如果没有找到nib文件,它尝试寻找一个与ViewController类名匹配的nib文件。
    • 如果没有可用的nib文件,那么它创建一个空的UIView作为它的view。

    最后还要考虑一个重要的情况:内存不足警告。当程序收到内存警告的时候,会调用每一个ViewController的didReceiveMemoryWarning方法,我们需要做出相应,释放程序中暂时不需要的资源;通常都会重写该方法,但记得重写的时候要调用super的该方法。

    iOS3.0 - iOS6.0期间,didReceiveMemoryWarning方法会判断当前ViewController的view是否显示在window上,如果没有显示在window上,则didReceiveMemoryWarning会自动将ViewController的view以及其所有子view全部销毁,然后调用View Controller的viewDidUnload方法。但是从iOS6.0开始,viewDidUnload和viewWillUnload这两个方法已被废除,收到low-memory时系统不会释放view,而只是释放controller的resource。

    一种常见处理内存警告的方式:

    复制代码
    - (void)didReceiveMemoryWarning
    {
        [super didReceiveMemoryWarning];
        
        float ver = [[[UIDevice currentDevice] systemVersion] floatValue];
        
        if(ver >= 6.0f)
        {
            if(self.isViewLoaded && !self.view.window)
            {
                self.view = nil; //确保下次重新加载
            }
        }
    }
    复制代码

    上面的代码先取得当前iOS系统的版本号,如果是iOS6.0或以上版本,进一步判断视图是否被装载进内存,并且是否为当前视图,在这两个条件都满足(已经装载进内存&&不是当前视图)时,将self.view设置为nil,这样就能保证再调用该ViewController时,loadView和viewDidLoad被再次调用。

    我们在xcode调试器里模拟内存警告,监控此时切换的状态:

    case 4. 当已切换至subVC,模拟内存警告,并返回mainVC,不处理didReceiveMemoryWarning。

    Received memory warning.

    main didReceiveMemoryWarning

    sub didReceiveMemoryWarning

    sub viewWillDisappear

    main viewWillAppear

    main viewDidAppear

    sub viewDidDisappear

    sub dealloc

     

    case 5. 当已切换至subVC,模拟内存警告,并返回mainVC,处理didReceiveMemoryWarning。

    Received memory warning.

    main didReceiveMemoryWarning

    sub didReceiveMemoryWarning

    main loadView

    main viewDidLoad

    sub viewWillDisappear

    main viewWillAppear

    main viewDidAppear

    sub viewDidDisappear

    sub dealloc

     

    可以很明显的看出,当处理了didReceiveMemoryWarning后,重新执行了非当前视图的loadView和viewDidLoad方法。

     

    init/initWithCoder

    loadView

    viewDidLoad

    viewWillAppear

    viewWillLayoutSubviews
    viewDidLayoutSubviews
    viewDidAppear
    viewWillDisappear
    viewDidDisappear

  • 相关阅读:
    HDU 2544 最短路
    HDU 3367 Pseudoforest
    USACO 2001 OPEN
    HDU 3371 Connect the Cities
    HDU 1301 Jungle Roads
    HDU 1879 继续畅通工程
    HDU 1233 还是畅通工程
    HDU 1162 Eddy's picture
    HDU 5745 La Vie en rose
    HDU 5744 Keep On Movin
  • 原文地址:https://www.cnblogs.com/shidaying/p/4146358.html
Copyright © 2011-2022 走看看