// Re-entrant calls do nothing; the outermost call will finish the job. if (loading) return; loading = YES;
void *pool = objc_autoreleasePoolPush();
do { // 1. Repeatedly call class +loads until there aren't any more //先调用类中的+load方法 while (loadable_classes_used > 0) { //先入先出处理+load函数列表 call_class_loads(); } // 2. Call category +loads ONCE //再调用分类中的+load函数 more_categories = call_category_loads();
// 3. Run more +loads if there are classes OR more untried categories } while (loadable_classes_used > 0 || more_categories);
objc_autoreleasePoolPop(pool);
loading = NO; }
staticvoid call_class_loads(void) { int i; // Detach current loadable list. struct loadable_class *classes = loadable_classes; int used = loadable_classes_used; loadable_classes = NULL; loadable_classes_allocated = 0; loadable_classes_used = 0; // Call all +loads for the detached list. //先入先出的遍历顺序,调用父类函数先于子类 for (i = 0; i < used; i++) { Class cls = classes[i].cls; //获得+load的函数指针 load_method_t load_method = (load_method_t)classes[i].method; if (!cls) continue;
if (PrintLoading) { _objc_inform("LOAD: +[%s load]\n", _class_getName(cls)); } //注意:是通过函数指针直接调用,而非使用objc_msgSend,因此不会走runtime调用过程。 (*load_method)(cls, SEL_load); } // Destroy the detached list. if (classes) _free_internal(classes); }
staticBOOL call_category_loads(void) { .... // Call all +loads for the detached list. for (i = 0; i < used; i++) { Category cat = cats[i].cat; load_method_t load_method = (load_method_t)cats[i].method; Class cls; if (!cat) continue;
IMP prepareForMethodLookup(Class cls, SEL sel, BOOL init, id obj) { rwlock_assert_unlocked(&runtimeLock);
if (!isRealized(newcls(cls))) { rwlock_write(&runtimeLock); realizeClass(newcls(cls)); rwlock_unlock_write(&runtimeLock); }
//调用_class_initialize对类进行初始化 if (init && !_class_isInitialized(cls)) { _class_initialize (_class_getNonMetaClass(cls, obj)); // 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 }
// Make sure super is done initializing BEFORE beginning to initialize cls. // See note about deadlock above. //递归,保证父类先于子类初始化 supercls = _class_getSuperclass(cls); if (supercls && !_class_isInitialized(supercls)) { _class_initialize(supercls); } ..... if (reallyInitialize) { // We successfully set the CLS_INITIALIZING bit. Initialize the class. // Record that we're initializing this class so we can message it. _setThisThreadIsInitializingClass(cls); // Send the +initialize message. // Note that +initialize is sent to the superclass (again) if // this class doesn't implement +initialize. 2157218 if (PrintInitializing) { _objc_inform("INITIALIZE: calling +[%s initialize]", _class_getName(cls)); } //通过objc_msgSend调用+initialize函数 ((void(*)(Class, SEL))objc_msgSend)(cls, SEL_initialize);
if (PrintInitializing) { _objc_inform("INITIALIZE: finished +[%s initialize]", _class_getName(cls)); } // Done initializing. // If the superclass is also done initializing, then update // the info bits and notify waiting threads. // If not, update them later. (This can happen if this +initialize // was itself triggered from inside a superclass +initialize.) ..... return; } ...... }