iOS APP加载流程

79 阅读1分钟

一 整体流程

  1. dyld:bootstrapstart:slide、栈溢出保护
  2. dyld:main:
  • 上下文
    
  • 环境变量
    
  • 共享缓存
    
  • reloadallimage如下
    
  • 1.实例化主程序
    
  • 2.加载动态库
    
  • 3.符号替换
    
  • `main初始化方法流程:下面有详细解释流程`
    
  • main
    

二 关键流程:main初始化方法流程

  • 遍历镜像,单个镜像递归初始化:recursiveInitialization
  • recursiveInitialization单个镜像初始化完毕后,调用notifySingle
  • notifySingle调用注册好的loadimages方法
  • loadimages内部调用遍历调用load方法(实际上是objc库将loadimages地址注册传过去的)

重点:loadimages 注册时机如下: recursiveInitialization->doInitialization->doImageInit(关键点 第一次调用会调用libSystemInitialized->_objc_init->注册loadimages)

源码解释如下

void ImageLoaderMachO::doImageInit(){
    if ( ! dyld::gProcessInfo->libSystemInitialized ) {

            dyld::throwf("-init function in image (%s) that does not link with libSystem.dylib\n", this->getPath());

    }
}

三 图示

  1. dyld简易图示

2.文字描述 initializeMainExecutable总结:

  • runInitializers->processInitializers中,遍历recursiveInitialization
  • 第一次执行时,进行libsystem初始化——doInitialization->doImageInit-> libSystemInitialized
  • libsystem的初始化,会调用起libdispatch_initlibdispatch初始化会调用_os_object_init, 内部调用了_objc_init
  • _objc_init中注册并保存了map_imagesload_imagesunmap_image函数地址
  • 注册完毕继续回到recursiveInitialization递归下一次调用 3.具详细流程如下

参考文章如下 掘金:详细 简书