美文网首页
iOS【调用时机】+load和+initialize

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

作者: iCuiCui | 来源:发表于2018-03-22 15:56 被阅读7次

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

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

    1.1 + initialize 方法:

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

    1.2+ load 方法:

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

    2.实例

    2.1 + load

    #pragram ---main函数中的代码---
    #import <UIKit/UIKit.h>
    #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

          本文链接:https://www.haomeiwen.com/subject/vwggqftx.html