iOS - +load與+ initialize -init
阿新 • • 發佈:2018-11-28
一、+ initialize 方法和+load 呼叫時機
- 首先說一下 + initialize 方法:蘋果官方對這個方法有這樣的一段描述:這個方法會在 第一次初始化這個類之前 被呼叫,我們用它來初始化靜態變數。
-
- load 方法會在載入類的時候就被呼叫,也就是 ios 應用啟動的時候,就會載入所有的類,就會呼叫每個類的 + load 方法。
- 之後我們結合程式碼來探究一下 + initialize 與 + load 兩個方法的呼叫時機,首先是 + 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的Son類--- #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
這說明在我並沒有對類做任何操作的情況下,+load 方法會被預設執行,並且是在 main 函式之前執行的。2015-10-27 15:21:07.545 initialize[11637:334237] +[Person load] 2015-10-27 15:21:07.546 initialize[11637:334237] +[Girl load] 2015-10-27 15:21:07.546 initialize[11637:334237] main
- 接下來我們來檢視一下 + initialize 方法,先在 ViewController 中建立 Person 和 Girl 物件:
下面我們來看一下輸出日誌:#import "ViewController.h" #import "Person.h" #import "Son.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
通過這個實驗我們可以確定兩點:2015-10-27 15:33:56.195 initialize[11711:342410] +[Person load] 2015-10-27 15:33:56.196 initialize[11711:342410] +[Girl load] 2015-10-27 15:33:56.197 initialize[11711:342410] main 2015-10-27 15:33:56.259 initialize[11711:342410] +[Person initialize] Person 2015-10-27 15:33:56.259 initialize[11711:342410] -[Person init] 2015-10-27 15:33:56.259 initialize[11711:342410] -[Person init] 2015-10-27 15:33:56.259 initialize[11711:342410] +[Girl initialize] 2015-10-27 15:33:56.260 initialize[11711:342410] -[Girl init] 2015-10-27 15:33:56.260 initialize[11711:342410] -[Girl init]
- + initialize 方法類似一個懶載入,如果沒有使用這個類,那麼系統預設不會去呼叫這個方法,且預設只加載一次;
- + initialize 的呼叫發生在 +init 方法之前。
- 接下來再探究一下 + initialize 在父類與子類之間的關係,建立一個繼承自 Person 類的 Son類:
看一下輸出日誌:#pragram ---ViewController 中的程式碼--- #import "ViewController.h" #import "Person.h" #import "Son.h" #import "Girl.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; Person * a = [Person new]; Person * b = [Person new]; Son*z = [Son new]; } @end
我們會發現 Person 類的 + initialize 方法又被呼叫了,但是檢視一下是子類 Son 呼叫的,也就是建立子類的時候,子類會去呼叫父類的 + initialize 方法。2015-10-27 15:44:55.762 initialize[12024:351576] +[Person load] 2015-10-27 15:44:55.764 initialize[12024:351576] +[Son load] 2015-10-27 15:44:55.764 initialize[12024:351576] +[Girl load] 2015-10-27 15:44:55.764 initialize[12024:351576] main 2015-10-27 15:44:55.825 initialize[12024:351576] +[Person initialize] Person 2015-10-27 15:44:55.825 initialize[12024:351576] -[Person init] 2015-10-27 15:44:55.825 initialize[12024:351576] -[Person init] 2015-10-27 15:44:55.826 initialize[12024:351576] +[Person initialize] Son 2015-10-27 15:44:55.826 initialize[12024:351576] -[Person init]
二、總結
- 如果你實現了 + load 方法,那麼當類被載入時它會自動被呼叫。這個呼叫非常早。如果你實現了一個應用或框架的 + load,並且你的應用連結到這個框架上了,那麼 + load 會在 main() 函式之前被呼叫。如果你在一個可載入的 bundle 中實現了 + load,那麼它會在 bundle 載入的過程中被呼叫。
- + initialize 方法的呼叫看起來會更合理,通常在它裡面寫程式碼比在 + load 裡寫更好。+ initialize 很有趣,因為它是懶呼叫的,也有可能完全不被呼叫。類第一次被載入時,
- + initialize 不會被呼叫。類接收訊息時,執行時會先檢查 + initialize 有沒有被呼叫過。如果沒有,會在訊息被處理前呼叫。
文/Mitchell(簡書作者)
原文連結:http://www.jianshu.com/p/9368ce9bb8f9
著作權歸作者所有,轉載請聯絡作者獲得授權,並標註“簡書作者”。