类方法load和initialize的比较

load苹果官方文档描述:
load
Invoked whenever a class or category is added to the Objective-C runtime;
implement this method to perform class-specific behavior upon loading.

每当类或类别被添加到Objective-C运行时时调用;实现此方法以在加载时执行特定于类的行为。

(load 文件被引用指的是编译时引用,而不是头文件被引用)) 类方法load和initialize的比较_第1张图片
调用顺序:
A class’s +load method is called after all of its superclasses’ +load methods.
A category +load method is called after the class’s own +load method.

父类 > 子类 > 子类的分类 > main > AppDelegate

应用:

一般用于黑魔法 Method Swizzle

+ (void)load
{
    // 交换MJ的国际化方法
    Method mjMethod = class_getClassMethod([NSBundle class],@selector(mj_localizedStringForKey:value:));
    Method myMethod = class_getClassMethod([NSBundle class], @selector(hook_mj_localizedStringForKey:value:));
    method_exchangeImplementations(mjMethod, myMethod);
}

或配置一些信息

+ (void)load
{
    LocalizableLanguage _language = LocalizableLanguage_CN;

    NSNumber * localizableLanguage =
    [[NSUserDefaults standardUserDefaults] objectForKey:__LocalizableLanguage_UserDefaults_Key];
    if (localizableLanguage == nil){
        NSString *language = [NSLocale preferredLanguages].firstObject;
        if (![language hasPrefix:@"zh"]) {
            _language = LocalizableLanguage_EN;
        }
    }else{
        _language = localizableLanguage.unsignedIntegerValue;
    }
    
    [[LocalizableManager globalManager] setLanguage:_language];
}
initialize
Initializes the class before it receives its first message.

在类接收到第一个消息之前初始化该类。

运行时在类或从类继承的任何类从程序中发送第一个消息之前,向程序中的每个类发送initialize。超类在子类之前接收此消息。

运行时以线程安全的方式向类发送初始化消息。也就是说,initialize由第一个线程运行,以向类发送消息,任何其他试图向该类发送消息的线程都会阻塞,直到initialize完成。

如果子类没有实现initialize(运行时将调用继承的实现),或者子类显式地调用[super initialize],则可以多次调用超类实现。如果你想保护自己不被多次运行,你可以这样组织你的实现:

+ (void)initialize{
    
    if (self == [ClassName class]) {
       ……执行初始化…
    }
}

因为initialize是以阻塞的方式调用的,所以将方法实现限制在尽可能少的工作量是很重要的。具体地说,任何接受其他类在其初始化方法中可能需要的锁的代码都可能导致死锁。因此,不应该依赖initialize进行复杂的初始化,而应该将其限制为直接的类本地初始化。

调用顺序:

main > 父类 > 子类

总结
·load是只要类所在的文件被引用就会被调用,而initialize在类或其子类的第一个方法调用之前被调用(runtime 中load方法不能认为第一个方法)。load在main函数之前调用,initialize在main函数之后调用。这两个方法会被自动调用。
· load和initialize方法都不用显示的调用父类的方法而是自动调用,即使子类没有initialize方法也会调用父类的方法如果子类显示调用[super initialize],则父类多次调用,load方法则不会调用父类。
·load方法通常用来进行Method Swizzle,initialize方法一般用于初始化全局变量或静态变量。
·load和initialize方法内部使用了锁,因此它们是线程安全的。实现时要尽可能保持简单,避免阻塞线程,不要再使用锁。
·每个类只调用initialize一次。如果希望为类和类的类别执行独立初始化,则应该实现load方法。

你可能感兴趣的:(Objective-C)