// // Entry point for dyld. The kernel loads dyld and jumps to __dyld_start which // sets up some registers and call this function. // // Returns address of main() in target program which __dyld_start jumps to // uintptr_t _main(const macho_header* mainExecutableMH, uintptr_t mainExecutableSlide, int argc, constchar* argv[], constchar* envp[], constchar* apple[], uintptr_t* startGlue) { .... }
// Return without taking locks if there are no +load methods here. found = false; //这里会找所有的class以及category的列表里面是否有+load方法 for (uint32_t i = 0; i < infoCount; i++) { if (hasLoadMethods((const headerType *)infoList[i].imageLoadAddress)) { found = true; break; } } if (!found) return nil; recursive_mutex_locker_tlock(loadMethodLock);
// Discover load methods // 搜集所有的+load方法 { rwlock_writer_tlock2(runtimeLock); found = load_images_nolock(state, infoCount, infoList); } //调用+load方法 if (found) { call_load_methods(); } ... } bool load_images_nolock(enum dyld_image_states state,uint32_t infoCount, const struct dyld_image_info infoList[]) { bool found = NO; uint32_t i; i = infoCount; while (i--) { const headerType *mhdr = (headerType*)infoList[i].imageLoadAddress; if (!hasLoadMethods(mhdr)) continue; // 搜集镜像中的load方法 prepare_load_methods(mhdr); found = YES; } return found; } voidprepare_load_methods(const headerType *mhdr) { size_t count, i; runtimeLock.assertWriting(); //1. 先搜集class中的+load方法 classref_t *classlist = _getObjc2NonlazyClassList(mhdr, &count); for (i = 0; i < count; i++) { schedule_class_load(remapClass(classlist[i])); } category_t **categorylist = _getObjc2NonlazyCategoryList(mhdr, &count); //2. 再搜集category中的+load方法 for (i = 0; i < count; i++) { category_t *cat = categorylist[i]; Class cls = remapClass(cat->cls); if (!cls) continue; // category for ignored weak-linked class realizeClass(cls); assert(cls->ISA()->isRealized()); add_category_to_loadable_list(cat); } } //递归实现,可以看到这里是先找父类中的+load方法,并放入到一个列表里面,所以在最终的class的load方法列表里面,父类的+load方法是先于子类的+load方法的 //大家可以看下add_class_to_loadable_list的实现,里面的分配内存策略使用了指数增长策略 staticvoidschedule_class_load(Class cls) { if (!cls) return; assert(cls->isRealized()); // _read_images should realize if (cls->data()->flags & RW_LOADED) return; // Ensure superclass-first ordering schedule_class_load(cls->superclass); add_class_to_loadable_list(cls); cls->setInfo(RW_LOADED); }