initWithCoder, initWithNibName, viewDidLoad的区别

在学习iOS教程时,总会遇到初始化的问题,由于分不清initWithCoder, initWithNibName, viewDidLoad等方法的区别,导致学习一头雾水。

在查阅资料之后,打算总结一下自己整理的资料。

定义:
1. initWithCoder: 将归档对象解档过程中调用(也就是在加载nib过程中调用的)。其中归档对象包括nib。
这里就涉及到归档(archive)以及nib等概念。
nib指的是IB(Interface Builder)下保存应用界面的文件,包括storyboard。
归档对象在我看来就是以某种形式存储在文件中,包括nib。

2. awakeFromNib: 当所有在nib中的对象都实例化后调用的方法。

以上两种方法都是利用stroyboard或者xib开发时才会调用的,如果你纯代码编写界面的话就会调用3.中的方法。
3.  initWithNibName:bundle: 在加载nib前调用,用于生成控制器的。

总结:
1)如果你用storyboard编写界面,则调用顺序为initWithCoder -> awakeFromNib
2)如果你用纯代码编写界面,则只调用了initWithNibName:bundle:

再说说application:didFinishLaunchingWithOptions: , viewDidLoad的定义和区别

application:didFinishLaunchingWithOptions:是在应用启动并进行初始化时调用的,在此过程中会实例化根视图控制器。
viewDidLoad 在视图控制器被实例化后,视图被加载到内存中时,会调用viewDidLoad方法。


我原以为调用顺序会是这样
application:didFinishLaunchingWithOptions: ->initWithCoder -> awakeFromNib ->viewDidLoad

但是当我写了一个简单demo后说明我地猜想是错误的。
附上代码和调用结果
//ViewController.m文件下

- (id)initWithCoder:(NSCoder *)aDecoder {
    
    if (self = [super initWithCoder:aDecoder]){
    
    }
    
    NSLog(@"initWithCoder");
    return self;
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
    
    }
    NSLog(@"initWithNibName");
    return self;
}

- (void)awakeFromNib
{
    NSLog(@"awakeFromNib");
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    NSLog(@"viewDidLoad");
}

//AppDelegate.m文件下

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    NSLog(@"application:didFinishLaunchingWithOptions:");
    return YES;
}

最后调用的结果为
2015-09-23 00:50:42.839 Order[3848:204656] initWithCoder
2015-09-23 00:50:42.840 Order[3848:204656] awakeFromNib
2015-09-23 00:50:42.842 Order[3848:204656] application:didFinishLaunchingWithOptions:
2015-09-23 00:50:42.844 Order[3848:204656] viewDidLoad

由于我使用的时storyboard,所以调用顺序是
initWithCoder -> awakeFromNib -> application:didFinishLaunchingWithOptions: -> viewDidLoad

由于我没有学习纯代码编写界面,会的同学可以自己写一下Demo,看一下结果。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
每个ios开发者对loadViewviewDidLoad肯定都很熟悉,虽然这两个函数使用上真的是非常简单,但是和类似的initWithNibName/awakeFromNib/initWithCoder放在一起还是非常容易让人混淆的. 昨天看了下苹果官方的相关文档以及几篇相关内容的网页(一 二 三),其实这个内容以前也看过,似乎也搞清楚了,可还是忘了.好急性不如烂笔头,这次一定要好好记下来. 大前提是UIViewController有一个UIView.同时,需要厘清两个概念,创建一个类和实例化一个类.在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会被调用. 如果你的对象是UIViewControler的子类,那么你必须调用- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle*)nibBundleOrNil;方法去调用NIB文件初始化自身,即使那没有使用nib文件也会调用这个函数(默认情况下init方法已经为你的做这件事情了),如果你调用这个方法,并传递的两个参数为空(nil),然后类会调用-loadView去读取一个名字和你的UIViewController名字相同的nib文件,来初始化自身。如果没有这样的nib文件,你必须调用-setView:来设置一个self.view。或者重载-loadView 方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值