一篇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的区别
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.initWithCoder 不需主动调用, 在xib建立ui对象的过程中被调用.
initWithCoder 在我看来是从文件里加载对象,需要指定文件的编码格式,比如UTF8,unicode等等。
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] ;
}
每个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会被调用.