zoukankan      html  css  js  c++  java
  • loadView和viewDidLoad及initWithNibName/awakeFromNib/initWithCoder、视图与控制器的生命周期

    每个ios开发者对loadViewviewDidLoad肯定都很熟悉,虽然这两个函数使用上真的是非常简单,但是和类似的initWithNibName/awakeFromNib/initWithCoder放在一起还是非常容易让人混淆的.

    一、loadView

    永远不要主动调用这个函数。view controller会在view的property被请求并且当前view值为nil时调用这个函数。如果你手动创建view,你应该重载这个函数。如果你用IB创建view并初始化view controller,那就意味着你使用initWithNibName:bundle:方法,这时,你不应该重载loadView函数。

    这个方法的默认实现是这样:先寻找有关可用的nib文件的信息,根据这个信息来加载nib文件,如果没有有关nib文件的信息,默认实现会创建一个空白的UIView对象,然后让这个对象成为controller的主view。

    所以,重载这个函数时,你也应该这么做。并把子类的view赋给view属性(property)(你create的view必须是唯一的实例,并且不被其他任何controller共享),而且你重载的这个函数不应该调用super。

    如果你要进行进一步初始化你的views,你应该在viewDidLoad函数中去做。在iOS 3.0以及更高版本中,你应该重载viewDidUnload函数来释放任何对view的引用或者它里面的内容(子view等等)。

    这个网上的资料都说的很不全面,尤其是蓝色字部分。

    二、viewDidLoad

    这个函数在controller加载了相关的views后被调用,而不论这些views存储在nib文件里还是在loadView函数中生成。而多数情况下是做nib文件的后续工作。

    网上资料对这个函数的描述则完全不对。

    三、viewDidUnload

    这个函数是viewDidLoad的对立函数。在程序内存欠缺时,这个函数被controller调用,来释放它的view以及view相关的对象。由于controller通常保存这view以及相关object的引用,所以你必须使用这个函数来放弃这些对象的所有权以便内存回收。但不要释放那些难以重建的数据。

    通常controller会保存nib文件建立的views的引用,但是也可能会保存着loadView函数创建的对象的引用。最完美的方法是使用合成器方法:

    1
    self.myCertainView = nil;

    这样合成器会release这个view,如果你没有使用property,那么你得自己显示释放这个view。

    网上对这个函数的描述含含糊糊,看了等于没看。

    四、结论

    所以流程应该是这样:

    (loadView/nib文件)来加载view到内存 ——>viewDidLoad函数进一步初始化这些view ——>内存不足时,调用viewDidUnload函数释放views

    —->当需要使用view时有回到第一步

    如此循环

        需要厘清两个概念,创建一个类和实例化一个类.在XCode中创建一个类和实例化一个类很容易区分,但是在IB(Interface Builder)中有时候就会迷糊.其实也很好区分,孤零零地创建了一个nib文件,没有和其他可被实例化的类有直接或间接关系的时候,这个类或这些类(一个nib文件俺也可能包含多个类)是没有机会被实例化的,所以这种情况只是通过ib创建了一个类,而没有实例化.真正的实例化还需要通过在Xcode用代码来读取这个nib文件.知道这两这的区别后这些方法也就容易辨认多了

    viewDidLoad其实没什么可混淆的,无论通过什么途径加载(Xcode或者IB,这里的加载属于实例化)完view后肯定会执行这个方法.

    loadView需要分两种情况.当你通过Xcode实例化一个类的时候就需要自己在controller中实现这个方法.而在IB中实例化就不需要实现它.

    initWithNibName这个方法是在controller的类在IB中创建,但是通过Xcode实例化controller的时候用的.

    awakeFromNib这个方法是一个类在IB中被实例化是被调用的.看了帖子发现大家都推荐使用viewDidLoad而不要使用awakeFromNib,应为viewDidLoad会被多次调用,而awakeFromNib只会当从nib文件中unarchive的时候才会被调用一次.实际测试中发现,当一个类的awakeFromNib被调用的时候,那么这个类的viewDidLoad就不会被调用了,这个感觉很奇怪.

    initWithCoder是一个类在IB中创建但在xocdde中被实例化时被调用的.比如,通过IB创建一个controller的nib文件,然后在xocde中通过initWithNibName来实例化这个controller,那么这个controller的initWithCoder会被调用.

    awakeFromNib 
    当.nib文件被加载的时候,会发送一个awakeFromNib的消息到.nib文件中的每个对象,每个对象都可以定义自己的awakeFromNib函数来响应这个消息,执行一些必要的操作。也就是说通过nib文件创建view对象是执行awakeFromNib 

    viewDidLoad 
    当view对象被加载到内存是就会执行viewDidLoad,所以不管通过nib文件还是代码的方式创建对象都会执行viewDidLoad

    *******************************************************************************************

    以视图的5种状态为基础,我们来系统的了解一下视图控制器的生命周期。在视图不同的生命周期,视图控制器会回调不同的方法。
     
    1
     
    viewDidLoad方法:视图控制器已被实例化,在视图被加载到内存中的时候调用该方法,这个时候视图并未出现。在该方法中通常进行的是对所控制的视图进行初始化处理。
     
    视图可见前后会调用viewWillAppear:方法和viewDidAppear:方法;视图不可见前后会调用viewWillDisappear:方法和viewDidDisappear:方法。 4个方法调用父类相应的方法以实现其功能, 编码时该方法的位置可根据实际情况做以调整,参见如下代码:
     
    [cpp] 
    -(void)viewWillAppear:(BOOL)animated  
      
    {  
      
    [super viewWillAppear:YES];  
      
    … …  
      
    }  
     
    -(void)viewWillAppear:(BOOL)animated
     
    {
     
    [super viewWillAppear:YES];
     
    … …
     
    }
     
     
    viewDidLoad方法在应用运行的时候只调用一次,而这上述4个方法可以被反复调用多次,它们的使用很广泛但同时也具有很强的技巧性。例如:有的应用会使用重力加速计,重力加速计会不断轮询设备以实时获得设备在z轴、x轴和y轴方向的重力加速度。不断的轮询必然会耗费大量电能进而影响电池使用寿命,我们通过利用这4个方法适时地打开或者关闭重力加速计来达到节约电能的目的。怎么使用这4个方法才能做到“适时”是一个值得思考的问题。
     
    iOS系统在低内存时情况下会调用didReceiveMemoryWarning:和viewDidUnload:方法。iOS6之后就不再使用viewDidUnload:,而仅支持didReceiveMemoryWarning:。didReceiveMemoryWarning:方法的主要职能是释放内存,包括视图控制器中的一些成员变量和视图的释放。现举例如下:
     
    [cpp] 
    - (void)didReceiveMemoryWarning {  
      
    self.button = nil;  
    self.myStringD = nil;  
    [myStringC release];  
      
    [super didReceiveMemoryWarning];  
    }  
     
    - (void)didReceiveMemoryWarning {
     
    self.button = nil;
    self.myStringD = nil;
    [myStringC release];
     
    [super didReceiveMemoryWarning];
    }
     
  • 相关阅读:
    laravel Eloquent 模型(也就是我本时说的Model)
    laravel 查询构建器(连贯操作)
    laravel 模版引擎使用
    laravel 数据库操作(表、字段)
    url重写(urlrewrite)的一些系统变量
    apache 图片防盗链
    在线制作api文档
    php 网络爬虫,爬一下花瓣的图片
    laravel 使用 session
    laravel 控制器构造方法注入request对象
  • 原文地址:https://www.cnblogs.com/ChrisYu/p/4663259.html
Copyright © 2011-2022 走看看