iOS【調用時機】+load和+initialize

Objective-C 有兩個神奇的方法:+load 和 +initialize,這兩個方法在類被使用時會自動調用。但是兩個方法的不同點會導致應用層面上性能的顯著差異。

1.+ initialize 方法和+load 調用時機

1.1 + initialize 方法:

會在第一次初始化這個類之前被調用,我們用它來初始化靜態(tài)變量。

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 方法會被默認執(zhí)行,并且是在 main 函數之前執(zhí)行的。

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 方法類似一個懶加載,如果沒有使用這個類,那么系統(tǒng)默認不會去調用這個方法,且默認只加載一次;
    • initialize 的調用發(fā)生在 +init 方法之前。

3.總結

如果你實現了 + load 方法,那么當類被加載時它會自動被調用。這個調用非常早。如果你實現了一個應用或框架的 + load,并且你的應用鏈接到這個框架上了,那么 + load 會在 main() 函數之前被調用。如果你在一個可加載的 bundle 中實現了 + load,那么它會在 bundle 加載的過程中被調用。

initialize方法的調用看起來會更合理,通常在它里面寫代碼比在 + load 里寫更好。+ initialize 很有趣,因為它是懶調用的,也有可能完全不被調用。類第一次被加載時,+ initialize 不會被調用。類接收消息時,運行時會先檢查 + initialize 有沒有被調用過。如果沒有,會在消息被處理前調用。

?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容