+ initialize 与 +load方法探究

2017-10-18  本文已影响0人  为什么划船不靠桨

一直以来对OC的+load 和 +initialize区分不是很清楚,最近好久没有更新过文章了,所以就研究了下这两个方法,在此进行记录.

一、开始测试

首先我们创建一个Person类,然后再创建一个Men类是为Person类的子类,并在两个类的实现文件中都敲下如下代码

+(void)load{
    NSLog(@"%s",__func__);
}
+(void)initialize{
    [super initialize];
    NSLog(@"%s %@",__func__,[self class]);
}
- (instancetype)init{
    if (self = [super init]) {
        NSLog(@"%s",__func__);
    }
    return self;
}

在main.m的main函数中敲下如下代码

NSLog(@"%s",__func__);

如图


图片发自简书APP

直接运行程序,我们可以看到输出结果为

2017-10-18 14:13:56.093471+0800 xcode99[7078:196795] +[Person load]
2017-10-18 14:13:56.094298+0800 xcode99[7078:196795] +[Men load]
2017-10-18 14:13:56.094649+0800 xcode99[7078:196795] main

这说明在我并没有对类做任何操作的情况下,+load 方法会被默认执行,并且是在 main 函数之前执行的。也就是说iOS应用启动的时候,就会加载所有的类,就会调用每个类的 + load 方法,并且先加载父类的方法再调用子类的方法.

然后再控制器中创建Person类和Men类的对象

Person *p1 = [[Person alloc]init];
Person *p2 = [[Person alloc]init];
    
Men *m1 = [[Men alloc]init];
Men *m2 = [[Men alloc]init];

运行程序,我们来看下输出日志

2017-10-18 14:56:15.042537+0800 xcode99[7901:225873] +[Person load]
2017-10-18 14:56:15.043343+0800 xcode99[7901:225873] +[Men load]
2017-10-18 14:56:15.043758+0800 xcode99[7901:225873] main
2017-10-18 14:56:15.313257+0800 xcode99[7901:225873] +[Person initialize] Person
2017-10-18 14:56:15.313403+0800 xcode99[7901:225873] -[Person init]
2017-10-18 14:56:15.313509+0800 xcode99[7901:225873] -[Person init]
2017-10-18 14:56:15.313605+0800 xcode99[7901:225873] +[Person initialize] Men
2017-10-18 14:56:15.313829+0800 xcode99[7901:225873] +[Men initialize] Men
2017-10-18 14:56:15.313924+0800 xcode99[7901:225873] -[Person init]
2017-10-18 14:56:15.314005+0800 xcode99[7901:225873] -[Men init]
2017-10-18 14:56:15.314087+0800 xcode99[7901:225873] -[Person init]
2017-10-18 14:56:15.314170+0800 xcode99[7901:225873] -[Men init]

1、+ initialize 方法类似一个懒加载,并且+ initialize 的调用发生在 +init 方法之前,如果没有使用这个类,那么系统默认不会去调用这个方法,且默认只加载一次。

2、若父类重写了+ initialize,当创建子类的时候,子类会去调用父类的 + initialize 方法。

然后我又分别为这两个类创建了分类,将实现文件中的三个方法直接拷贝到了分类文件中,再次运行

2017-10-18 14:59:18.452196+0800 xcode99[7984:228215] +[Person load]
2017-10-18 14:59:18.453932+0800 xcode99[7984:228215] +[Men load]
2017-10-18 14:59:18.454412+0800 xcode99[7984:228215] +[Person(Category) load]
2017-10-18 14:59:18.455121+0800 xcode99[7984:228215] +[Men(Category) load]
2017-10-18 14:59:18.455820+0800 xcode99[7984:228215] main
2017-10-18 14:59:18.725084+0800 xcode99[7984:228215] +[Person(Category) initialize] Person
2017-10-18 14:59:18.725271+0800 xcode99[7984:228215] -[Person(Category) init]
2017-10-18 14:59:18.725351+0800 xcode99[7984:228215] -[Person(Category) init]
2017-10-18 14:59:18.725468+0800 xcode99[7984:228215] +[Person(Category) initialize] Men
2017-10-18 14:59:18.725565+0800 xcode99[7984:228215] +[Men(Category) initialize] Men
2017-10-18 14:59:18.725640+0800 xcode99[7984:228215] -[Person(Category) init]
2017-10-18 14:59:18.725709+0800 xcode99[7984:228215] -[Men(Category) init]
2017-10-18 14:59:18.725792+0800 xcode99[7984:228215] -[Person(Category) init]
2017-10-18 14:59:18.728170+0800 xcode99[7984:228215] -[Men(Category) init]

说明当分类中的+ load 方法依旧是优先于main方法执行的,并且不会覆盖原来的类中的+ load方法,但是是先调用类中的,再调用类别中的;而原来类中的+ initialize方法则会被分类中的+ initialize全部覆盖掉.

上一篇下一篇

猜你喜欢

热点阅读