+initialize方法的原理

65 阅读1分钟

IMP lookUpImpOrForward(id inst, SEL sel, Class cls, int behavior) { const IMP forward_imp = (IMP)_objc_msgForward_impcache; IMP imp = nil; Class curClass;

runtimeLock.assertUnlocked();

// 小概率事件
if (fastpath(behavior & LOOKUP_CACHE)) {
    imp = cache_getImp(cls, sel);
    if (imp) goto done_nolock;
}
runtimeLock.lock();

checkIsKnownClass(cls);

// 很可能 cls 是有值的,编译器可以不用每次都读取 return nil 指令(小概率事件) if (!cls->isRealized()) { realizeClass(cls); } if (slowpath(!cls->isRealized())) { cls = realizeClassMaybeSwiftAndLeaveLocked(cls, runtimeLock); // runtimeLock may have been dropped but is now locked again }

if (initialize  &&  !cls->isInitialized()) {
    runtimeLock.unlock();
    _class_initialize (_class_getNonMetaClass(cls, inst));
    runtimeLock.lock();
    // If sel == initialize, _class_initialize will send +initialize and 
    // then the messenger will send +initialize again after this 
    // procedure finishes. Of course, if this is not being called 
    // from the messenger then it won't happen. 2778172
}