load方法和initialize方法類似點
1. 都只會調用一次2. 父類在子類之前加載
復制代碼
不同點在于:
1. 加載時間不同,load方法在main()函數前進行調用,initialize在第一次調用類的所屬方法時在調用<可能永遠不調用>。2. load方法不會被Category覆蓋。
復制代碼
initialize源碼
//向對象發送消息時,lookUpImpOrForward函數判斷對象是否初始化,沒有初始化則先初始化在調用類的方法
IMP lookUpImpOrForward(Class cls, SEL sel, id inst, bool initialize, bool cache, bo ol resolver);
//第一次調用類
if (initialize && !cls->isInitialized()) {_class_initialize (_class_getNonMetaClass(cls, inst));}// 第一次調用類的方法,初始化對象
void _class_initialize(Class cls) {Class supercls;bool reallyInitialize = NO;// 遞歸初始化父類supercls = cls->superclass;if (supercls && !supercls->isInitialized()) {_class_initialize(supercls);}{monitor_locker_t lock(classInitLock);if (!cls->isInitialized() && !cls->isInitializing()) {cls->setInitializing();reallyInitialize = YES;}}if (reallyInitialize) { _setThisThreadIsInitializingClass(cls);if (MultithreadedForkChild) { performForkChildInitialize(cls, supercls);return;}@try {// 通過objc_msgSend函數調用initialize方法callInitialize(cls);}@catch (...) { @throw;}@finally {// 執行initialize方法后,進行系統的initialize過程lockAndFinishInitializing(cls, supercls);}return;}else if (cls->isInitializing()) {if (_thisThreadIsInitializingClass(cls)) {return;} else if (!MultithreadedForkChild) {waitForInitializeToComplete(cls);return; } else {_setThisThreadIsInitializingClass(cls);performForkChildInitialize(cls, supercls);}}
}
復制代碼