1. 程式人生 > >關於load和initialize,《深入剖析load和initialize方法》

關於load和initialize,《深入剖析load和initialize方法》

在Objective-C中,NSObject是根類,而NSObject.h的標頭檔案中前兩個方法就是load和initialize兩個類方法,本篇文章就對這兩個方法進行詳細、深入的剖析。
就像Application有生命週期回撥方法一樣,在Objective-C的類被載入和初始化的時候,也可以收到方法回撥,可以在適當的情況下做一些定製處理。而這正是load和initialize方法可以幫我們做到的。

+(void)load;
+(void)initialize;

上述程式碼都是系統方法,可以看到兩個方法都是類方法並且沒有返回值。從如上宣告上來看,也許這兩個方法和其它的類方法相比沒什麼特別。但是,這兩個方法具有一定的“特殊性”,這也是這兩個方法經常會被放在一起特殊提到的原因。詳細請看如下幾小節的整理。

load和initialize有很多共同特點,下面簡單列一下:

在不考慮開發者主動使用的情況下,系統最多會呼叫一次
如果父類和子類都被呼叫,父類的呼叫一定在子類之前
都是為了應用執行提前建立合適的執行環境
在使用時都不要過重地依賴於這兩個方法,除非真正必要。

load方法呼叫時機比較早,執行環境有不確定因素。具體說來,在iOS上通常就是App啟動時進行載入,但當load呼叫的時候,並不能保證所有類都載入完成且可用,必要時還要自己負責做auto release處理。
補充上面一點,對於有依賴關係的兩個庫中,被依賴的類的load會優先呼叫。但在一個庫之內,呼叫順序是不確定的。
對於一個類而言,沒有load方法實現就不會呼叫,不會考慮對NSObject的繼承。
一個類的load方法不用寫明[super load],父類就會收到呼叫,並且在子類之前。
Category的load也會收到呼叫,但順序上在主類的load呼叫之後。
不會直接觸發initialize的呼叫。

initialize的自然呼叫是在第一次主動使用當前類的時候(lazy,這一點和Java類的“clinit”的很像)。
在initialize方法收到呼叫時,執行環境基本健全。
initialize的執行過程中是能保證執行緒安全的。
和load不同,即使子類不實現initialize方法,會把父類的實現繼承過來呼叫一遍。注意的是在此之前,父類的方法已經被執行過一次了,同樣不需要super呼叫。
由於initialize的這些特點,使得其應用比load要略微廣泛一些。