OC中init、initWithFrame、initWithCoder、awakeFromNib调用情况

假定我们需要自定义一个View,命名为MyView,当我们需要使用它当使用,一般情况下我们可以手写代码创建或者从Xib、Storyboard中创建。

@implementation MyView

- (instancetype)init
{
    self = [super init]; // call the designated initializer
    if (self) {
        // Custom initialization
        NSLog(@"init");
    }
    return self;
}
- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self commonInit];
        NSLog(@"initWithFrame");
    }
    return self;
}

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

- (instancetype)awakeFromNib {
    NSLog(@"awakeFromNib");
    [super awakeFromNib];
}

- (void)commonInit
{
    // do any initialization that's common to both -initWithFrame:
    // and -initWithCoder: in this method
}

一、不同创建方式的调用情况

1、手写init创建

MyView *myView =[ [MyView alloc] init];
当使用该方法创建时,init和initWithFrame方法都调用了。

2、手写initWithFrame创建

MyView *myView =[ [MyView alloc] initWithFrame:CGRectZero];
当使用该方法创建时,initWithFrame调用了。

3、使用Xib、Storyboard创建

initWithCoder、awakeFromNib会调用。

二、几种方法的区别

1、init 和 initWithFrame:

在使用[[Class alloc]init];方法创建对象时,会先调用的是initWithFrame方法,然后再调用init方法。
关于init


OC中init、initWithFrame、initWithCoder、awakeFromNib调用情况_第1张图片
58b65c25d3dc0.jpg

可知:
1)init是让子类实现初始化一个新对象的方法
2)NSObject类的init没有初始化操作,只是简单的返回了一个self指针in 在UIView 调用 [super init] i类似于调用 [super initWithFrame:CGRectZero]的效果。所以手写创建时,只需要在initWithFrame方法中写初始化设置的代码,可以确保代码被执行。不需要在init和initWithFrame方法中各写一次。

2、awakeFromNib: 和 initWithCoder:

awakeFromNib: 从xib或者storyboard加载完毕就会调用
initWithCoder: 只要对象是从文件解析来的,就会调用
同时存在会先调用initWithCoder:

3、initWithCoder: 和 initWithFrame:

initWithCoder: 和 initWithFrame:都是指定初始化方法(designated initializer)。
initWithCoder:使用文件加载的对象调用(如从xib或stroyboard中创建)
initWithFrame:使用代码加载的对象调用(使用纯代码创建)
注意:所以为了同时兼顾从文件和从代码解析的对象初始化,要同时在initWithCoder: 和 initWithFrame: 中进行初始化。

4、awakeFromNib

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

最后

在初始化控件的代码时,由于其他人用手写或是从xib或stroyboard中创建不得而知,为安全起见,可以将初始化设置的代码分别在initWithFrame和initWithCoder中都调用一下,以保证初始化设置的代码都能被调用。

参考文献:
https://github.com/oa414/objc-zen-book-cn/#designated-initializer
http://www.cnblogs.com/yajunLi/p/6344023.html?hmsr=toutiao.io
https://stackoverflow.com/questions/7226239/objective-c-custom-view-and-implementing-init-method
http://www.iosugar.com/2017/03/01/UIView-init-and-initWithFrame-call-relationship/

你可能感兴趣的:(OC中init、initWithFrame、initWithCoder、awakeFromNib调用情况)