iOS【调用时机】+load和+initialize

Objective-C 有两个神奇的方法:+load 和 +initialize,这两个方法在类被使用时会自动调用。但是两个方法的不同点会导致应用层面上性能的显著差异。

1.+ initialize 方法和+load 调用时机

1.1 + initialize 方法:

会在第一次初始化这个类之前被调用,我们用它来初始化静态变量。

1.2+ load 方法:

会在加载类的时候就被调用,也就是 ios 应用启动的时候,就会加载所有的类,就会调用每个类的 + load 方法。

2.实例

2.1 + load

#pragram ---main函数中的代码---
#import 
#import"AppDelegate.h"
int main(int argc, char * argv[]) {
    NSLog(@"%s",__func__);
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

#pragram ---基于NSObject的Person类---
#import "Person.h"
@implementation 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;
}
@end

#pragram ---基于Person的Girl类---
#import "Girl.h"
@implementation Girl
+ (void)load{
    NSLog(@"%s ",__func__);
    
}
+ (void)initialize{
    [super initialize];
    NSLog(@"%s ",__func__);
}
- (instancetype)init{
    if (self = [super init]) {
        NSLog(@"%s",__func__);
    } return self;
}
@end

输出日志如下:

2018-03-22 15:49:19.981240+0800 test[51130:1824513] +[Person load]
2018-03-22 15:49:19.981703+0800 test[51130:1824513] +[Girl load]
2018-03-22 15:49:19.981913+0800 test[51130:1824513] main

这说明在我并没有对类做任何操作的情况下,+load 方法会被默认执行,并且是在 main 函数之前执行的。

2.2 + initialize

#import "ViewController.h"
#import "Person.h"
#import "Girl.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    Person * a = [Person new];
    Person * b = [Person new];
    Girl *c = [Girl new];
    Girl *d = [Girl new];
}
@end

输出日志如下:

2018-03-22 15:51:50.257071+0800 test[51204:1827692] +[Person load]
2018-03-22 15:51:50.257721+0800 test[51204:1827692] +[Girl load]
2018-03-22 15:51:50.258080+0800 test[51204:1827692] main
2018-03-22 15:51:50.385627+0800 test[51204:1827692] +[Person initialize]--Person
2018-03-22 15:51:50.385776+0800 test[51204:1827692] -[Person init]
2018-03-22 15:51:50.385865+0800 test[51204:1827692] -[Person init]
2018-03-22 15:51:50.385976+0800 test[51204:1827692] +[Person initialize]--Girl
2018-03-22 15:51:50.386088+0800 test[51204:1827692] +[Girl initialize]
2018-03-22 15:51:50.386254+0800 test[51204:1827692] -[Person init]
2018-03-22 15:51:50.386362+0800 test[51204:1827692] -[Girl init]
2018-03-22 15:51:50.386497+0800 test[51204:1827692] -[Person init]
2018-03-22 15:51:50.386739+0800 test[51204:1827692] -[Girl init]

通过这个实验我们可以确定两点:

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

3.总结

如果你实现了 + load 方法,那么当类被加载时它会自动被调用。这个调用非常早。如果你实现了一个应用或框架的 + load,并且你的应用链接到这个框架上了,那么 + load 会在 main() 函数之前被调用。如果你在一个可加载的 bundle 中实现了 + load,那么它会在 bundle 加载的过程中被调用。

initialize方法的调用看起来会更合理,通常在它里面写代码比在 + load 里写更好。+ initialize 很有趣,因为它是懒调用的,也有可能完全不被调用。类第一次被加载时,+ initialize 不会被调用。类接收消息时,运行时会先检查 + initialize 有没有被调用过。如果没有,会在消息被处理前调用。

你可能感兴趣的:(iOS【调用时机】+load和+initialize)