Objective-C中有兩個方法比較特殊,他們會在Runtime時根據情況自動調用,下面我們簡單分析一下調用時機以及使用場景~
一般在iOS初中級面試時偶爾會被問到load和initialize方法,我出了一道題,估計會搞暈很多人。大家來看一下下面的程序以及圖一會輸出什麼?(這個Demo請點擊這裡查看詳情)
//Father.m + (void)load { NSLog(@"Father:%s %@", __FUNCTION__, [self class]); } + (void)initialize { NSLog(@"Father:%s %@", __FUNCTION__, [self class]); } //Son.m Class Son Extends Father + (void)load { NSLog(@"Son:%s %@", __FUNCTION__, [self class]); } //Son+load.m + (void)load { NSLog(@"Son+load:%s %@", __FUNCTION__, [self class]); } //Other.m + (void)load { NSLog(@"Other:%s %@", __FUNCTION__, [self class]); } + (void)initialize { NSLog(@"Other:%s %@", __FUNCTION__, [self class]); } //Other+initialize.m + (void)initialize { NSLog(@"Other+initialize:%s %@", __FUNCTION__, [self class]); } //main.m int main(int argc, char * argv[]) { NSLog(@"Main method start!"); return 0; }
我是圖一
答案是:
首先來說一下調用時機:
+load()方法:官方文檔上說Invoked whenever a class or category is added to the Objective-C runtime;,意思是說當類被加載到runtime的時候就會運行,也就是說是在main.m之前~會根據Compile Sources中的順序來加載,但還有一個需注意的加載順序
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.
意思是說有繼承關系的會先調用父類+load,擴展的類在所有的類在方法之後再開始擴展方法的+load,每個類只會調用一次+load
+initialize()方法:官方文檔上說Initializes the class before it receives its first message.意思是在類接收第一條消息之前初始化類
值得注意的點是:類初始化的時候每個類只會調用一次+initialize(),如果子類沒有實現+initialize(),那麼將會調用父類的+initialize(),也就是意味著父類的+initialize()可能會被多次調用
最後說下使用場景:
+load():通常用來進行Method Swizzle,盡量避免過於復雜以及不必要的代碼
+initialize():一般用於初始化全局變量或靜態變量
EOF:
好了,通過上述的所概括應該能知道為什麼答案是那樣了~另外如果文章中有什麼錯誤或者意見請大家多多指教~