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);
}
}
}
複製程式碼