1.什么是DYLD
DYLD是动态链接器,是用来加载所有的库以及可执行文件的。
DYLD源码 密码:0n16
2.DYLD加载一个应用程序流程
2.1创建工程
创建一个名为DYLDDemo的工程,iOS版本号设定为iOS13.0,在main函数打上断点,链接真机,调试运行,运行到断点的时候,使用bt查看当前函数调用栈,如下图所示:

上面的结果并不是我们想要的,因为上面的函数调用栈没有显示完全,因此我们在ViewController中的load方法中打断点,再次查看其函数调用栈,如下所示:
bt
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
frame #0: 0x0000000104079f0c DYLDDemo`+[ViewController load](self=ViewController, _cmd="load") at ViewController.m:18:1
frame #1: 0x00000001977bd21c libobjc.A.dylib`load_images + 928
frame #2: 0x000000010419e320 dyld`dyld::notifySingle(dyld_image_states, ImageLoader const*, ImageLoader::InitializerTimingList*) + 496
frame #3: 0x00000001041b0c4c dyld`ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) + 592
frame #4: 0x00000001041aebb8 dyld`ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) + 192
frame #5: 0x00000001041aec84 dyld`ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) + 96
frame #6: 0x000000010419e7f4 dyld`dyld::initializeMainExecutable() + 220
frame #7: 0x00000001041a3d88 dyld`dyld::_main(macho_header const*, unsigned long, int, char const**, char const**, char const**, unsigned long*) + 5500
frame #8: 0x000000010419d258 dyld`dyldbootstrap::start(dyld3::MachOLoaded const*, int, char const**, dyld3::MachOLoaded const*, unsigned long*) + 476
* frame #9: 0x000000010419d038 dyld`_dyld_start + 56
还可以使用(frame select 函数调用栈编号)来切换显示函数调用栈,如下图所示:

切换frame
2.2 DYLD源码分析
我们根据工程中函数调用栈的调用结果可以知道,load方法是在工程main函数调用之前调用的,而命名空间下的dyldbootstrap_dyld_start函数是最开始调用的方法,因此我们进入DYLD源码中去查看这个方法调用过程。
2.2.1 使用XCode打开下载的DYLD源码工程,搜索命名空间dyldbootstrap

搜索dyldbootstrap

image.png

搜索start方法
就从这个方法分析DYLD的加载流程
loadImage并不是dyld中的方法而是libobjc中的方法


image.png