iOS load方法与initialize方法

在 iOS 开发中,我们经常会使用 +load 方法来做一些在 main 函数之前的操作,比如方法交换(Method Swizzle)等。现在分析一下load方法跟initialize方法的调用顺序以及区别。

1.先看下load方法

尝试定义一个继承自 NSObject 的 Person 类,并对其添加两个分类 Life 和 Work;再定义一个 Student 类继承自 Person,并对其添加 School 分类。在以上所有类和分类中,均实现 +load:

#import "Person.h"

 

@implementation Person

+ (void)load {

    NSLog(@"Person %s", __func__);

}

@end

 

#import "Person+Life.h"

 

@implementation Person (Life)

+ (void)load {

    NSLog(@"Person+Life %s", __func__);

}

 

@end

 

 

 

#import "Person+Work.h"

 

@implementation Person (Work)

+ (void)load {

    NSLog(@"Person+Work %s", __func__);

}

 

@end

 

#import "Student.h"

 

@implementation Student

+ (void)load {

//    [super load];

    NSLog(@"Student %s", __func__);

}

@end

 

 

#import "Student+School.h"

 

@implementation Student (School)

+ (void)load {

    NSLog(@"Student+School %s", __func__);

}

@end

 

启动项目,打印结果如下,说明 +load 方法会在 main 函数之前被调用;且调用顺序总是先父类再子类再分类

 

当我们在一个类的子类的 +load 中 [super load] 又会调用到到底哪个类中呢(当然,在实际开发中这种情几乎不可能存在)?答案就是 [super load] 将调用到 Person 最后一个被编译的分类(Person+Work)中的 +load 方法,因为这里是消息发送,而不是通过方法指针。

应用:因为类或者分类一旦被加载到运行时,就会调用这个方法;因为加载时间特别早:所以可以利用这个特性进行一些处理

2.之后分析 initialize方法

在person与student类中添加init方法跟initialize方法,然后在 ViewController 中创建 Person 和 student 对象,如下:

#import "Person.h"

 

@implementation Person

-(instancetype)init{

    if (self = [super init]) {

        NSLog(@"%s",__func__);

    }

    return self;

}

+ (void)load {

    NSLog(@"Person %s", __func__);

}

+ (void)initialize{

    NSLog(@"Person %s",__func__);

}

@end

 

#import "Student.h"

 

@implementation Student

-(instancetype)init{

    if (self = [super init]) {

        NSLog(@"%s",__func__);

    }

    return self;

}

+ (void)load {

    NSLog(@"Student %s", __func__);

}

+ (void)initialize{

    NSLog(@"Student %s",__func__);

}

@end



@implementation ViewController

 

- (void)viewDidLoad {

    [super viewDidLoad];

    NSLog(@"%s",__func__);

    Person * per = [[Person alloc]init];

    Student * stu = [[Student alloc]init];

    // Do any additional setup after loading the view, typically from a nib.

}

 

启动项目,运行结果如下:

 

由此得出结论

  1. loadinitialize方法都会在实例化对象之前调用,以main函数为分水岭,前者在main函数之前调用,后者在之后调用。
  2. initialize方法的调用顺序是先父类再子类;是以懒加载的方式被调用的;

 

posted @ 2019-08-30 10:55  梅子~  阅读(1371)  评论(0编辑  收藏  举报