一、dyld的引出
1.首先在main函数打断点,可以看到在main之前libdyld.dylib`start
2.在load函数打断点,通过堆栈信息可以看到dyld做了大量的工作
3.dyld可以从苹果官网下载
地址: opensource.apple.com/release/mac…
二、dyld中main函数流程
1.全局搜索_dyld_start,根据注释可以知道最终是调用了dyldbootstrap::start
2.全局搜索dyldbootstrap,可以看到start函数
3.在start函数中,返回了_main
4.简单来看_main函数,直接看最后一行,返回result,在寻找result赋值的地方,发现和sMainExecutable有关,再找和sMainExecutable赋值相关的代码,在7009行可以看到
sMainExecutable = instantiateFromLoadedImage(mainExecutableMH, mainExecutableSlide, sExecPath);
5.instantiateFromLoadedImage初始化主程序
6.7241行initializeMainExecutable
7.runInitializers函数
8.processInitializers函数
9.recursiveInitialization函数(1654行依赖文件的加载完成通知,1662行本身加载完成通知)
10.notifySingle函数(1112行sNotifyObjCInit)
11.registerObjCNotifiers函数给sNotifyObjCInit赋值了
12._dyld_objc_notify_register函数调用了registerObjCNotifiers
13.在runtime源码中调用了dyld中的_dyld_objc_notify_register函数
14.在runtime源码_objc_init打断点,查看堆栈
15.下载libdispatch库,搜索_os_object_init函数
16.在libdispatch_init函数7923行中
17.下载libSystem库,搜索libSystem_initializer函数239行
18.回到dyld,搜索doModInitFunctions函数
2318行判断如果libSystemPath库没初始化完成,就会抛出异常
2326行func执行调用,2310行func = inits[j],即会调用libSystem_initializer
19.doInitialization函数
20.而调用doInitialization函数是在recursiveInitialization函数中
21.回到runtime _objc_init函数中
22.在dyld中 registerObjCNotifiers赋值了参数
23.搜索sNotifyObjCMapped,在notifyBatchPartial函数中调用
24.搜索sNotifyObjCInit,在notifySingle函数中
25.notifySingle函数调用是在recursiveInitialization函数中
26.工程中的加载顺序 load函数->C++函数->main函数
27.runtime中的load_images函数
28.prepare_load_methods函数
29.schedule_class_load函数
30.add_class_to_loadable_list函数收集load放在到loadable_classes中
31.getLoadMethod函数拿到所有类的load方法
32.递归调用load函数
33.断点看C++函数的调用栈
34.doInitialization函数是在recursiveInitialization函数中
35.上面的执行完毕之后执行main函数,在dyld_start中
最后整理下流程图