iphone+ios+loadView/viewDidLoad/initWithNibName/awakeFromNib/initWithCoder/initWithFrame

一篇e文得文章写得挺清楚

http://www.cimgf.com/2008/03/26/cocoa-tutorial-awakefromnib-vs-applicationdidfinishlaunching/

http://www.quora.com/Cocoa-API/What-is-the-difference-between-initWithCoder-initWithNibName-and-awakeFromNib

http://davychen.blog.51cto.com/3283671/653001

1。 initWithNibName:bundle 和 loadNibNamed的区别

  • initWithNibName:bundle: is a message sentto a view (or window) controller in order to create the controller; thus, before the nib is loaded. (Possibly long before. It is not part of the nib loading process.)
  • initWithNibName这个方法是在controller的类在IB中创建,但是通过Xcode实例化controller的时候用的.UIViewController’s initWithNibName:bundle: on the other hand is a way to initialize a view controller which (might) load its view from a nib. The method does not itself load the nib but just takes note of the name. The controller loads the nib lazily when the view is requested.
  • loadNibNamed这个方法是初始化view的时候用到的.NSBundle’s methods are the generic API to use for unarchiving NIBs. They do the actual work (together with NSNib).
  • 这两者的区别
  • initWithNibName:bundle: is convenience method declared in UIViewController and is available to its subclasses. This will initialize the view controller by loading the nib, probably by usingloadNibName:owner:options: method internally.
    initWithNibName:bundle: is unavailable to UIView and its subclasses. So we have to make use of loadNibName:owner:options: to load views.
    Custom cells are UIView subclasses and hence make use of loadNibName:owner:options:.
    Not much difference. initWithNibName:bundle: is a convenience method forUIViewController initialization.
    You are getting errors because of the reasons mentioned above.

2. initWithCoder/awakeFromNib/initWithFrame
  • initWithCoder: is a message sent to every object in an archive (including a nib) in order to unarchive it; thus, during the nib loading.
  • initWithCoder 不需主动调用, 在xib建立ui对象的过程中被调用.

    initWithCoder 在我看来是从文件里加载对象,需要指定文件的编码格式,比如UTF8,unicode等等。

  • awakeFromNib is a message sent to every object in a nib after all of its outlets are hooked up; thus, after the nib is loaded.当.nib文件被加载的时候,会发送一个awakeFromNib的消息到.nib文件中的每个对象,每个对象都可以定义自己的awakeFromNib函数来响应这个消息,执行一些必要的操作。也就是说通过nib文件创建view对象是执行awakeFromNib 。
  • awakeFromNib是一个只有在GUI对象被成功加载才调用的方法,而init方法是在GUI被创建前就已经调用了。当程序对Nib文件进行反序列化然后初始化时
  • 1)([[NSBundle mainBundle]loadNibNamed:@"MyView" owner:nil options:nil]; )会调用一次awakeFromNib
  • 2)但是如果你使用initWithNibName调入Nib时,awakeFromNib是不会被调用的。
  • 3)所以用以下代码运行程序时不执行awakeFromNib

    TestController *test = [[TestController alloc] initWithNibName:@"Test" bundle:nil];  
    [self.view addSubview:test.view]



    而viewDidLoad不管在什么情况下都会执行 

    loadView 此方法在控制器的view为nil的时候被调用。 此方法用于以编程的方式创建view的时候用到。 如

    - ( void ) loadView {
        UIView *view = [ [ UIView alloc] initWithFrame:[ UIScreen
    mainScreen] .applicationFrame] ;
        [ view setBackgroundColor:_color] ;
        self.view = view;
        [ view release] ;
    }

    你 在控制器中实现了loadView方法,那么你可能会在应用运行的某个时候被内存管理控制调用。 如果设备内存不足的时候, view 控制器会收到didReceiveMemoryWarning的消息。 默认的实现是检查当前控制器的view是否在使用。 如果它的view不在当前正在使用的view hierarchy里面,且你的控制器实现了loadView方法,那么这个view将被release, loadView方法将被再次调用来创建一个新的view。



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

昨天看了下苹果官方的相关文档以及几篇相关内容的网页(一 二 三),其实这个内容以前也看过,似乎也搞清楚了,可还是忘了.好急性不如烂笔头,这次一定要好好记下来.

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

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

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


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

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

你可能感兴趣的:(ios,object,xcode,iPhone,UIView,hierarchy)