程序加载过程

程序加载时,会加载静态库、动态库和二进制可执行文件等,由此引出几个问题:

  • 问题1❓:什么是静态库?什么是动态库?二者的区别是什么?
  • 问题2❓:app加载流程是怎样的?

当app启动时,系统内核做相应处理后,会交给dyld动态链接器继续处理,即内核态向用户态的切换
此时,dyld会加载相应的动态库,其中包括包含有runtime的动态库libSystem,最终,会调用runtime源码中的void _objc_init(void)函数,这里具体的加载过程,之后再另行总结整理

runtime加载入口函数

void _objc_init(void)
{
    static bool initialized = false;
    if (initialized) return;
    initialized = true;
    
    // fixme defer initialization until an objc-using image is found?
    environ_init();//对log日志系统的初始化
    tls_init();
    static_init();
    lock_init();//锁
    exception_init();//异常
    
    /*通过dyld动态链接器加载runtime所在的动态库libSystem,Runtime向dyld注册回调函数
      使用imageLoader加载新的image镜像加载,会执行对应的回调函数
     */
    _dyld_objc_notify_register(&map_images, load_images, unmap_image);
}
  • ❗️ image就是一个二进制文件,包括可执行文件(就是在xcode中Products文件下的可执行二进制文件,直接点击可以直接运行)和动态库;ImageLoader就是将 image加载进内存的
  • ❗️ 当通过一个叫做ImageLoader加载新的image镜像时,就会调用_dyld_objc_notify_register ()注册的这三个回调函数中的&map_images函数和load_images函数,这三个函数就是runtime向dyld注册的三个回调函数
  • ❗️ runtime会不停的递归加载image,并且有缓存机制,直至所有的image加载完成,才会最终执行main函数

回调函数map_images

map_images

void
map_images(unsigned count, const char * const paths[],
          const struct mach_header * const mhdrs[])
{
    rwlock_writer_t lock(runtimeLock);
    return map_images_nolock(count, paths, mhdrs);
 }
  • ❗️管理可执行文件和动态库中所有的符号,例如:Class,Protocol,Selector,IMP等,比如说Class类通过一个表进行管理;Protocol进行对象的关联,对Selecotr建立表进行管理

map_images_nolock

 if (hCount > 0) {
        _read_images(hList, hCount, totalClasses, unoptimizedTotalClasses);//这里读取images
    }

_read_images

  • ❗️该函数主要功能就是将类、方法、协议存储到对应的哈希表中


    程序加载过程_第1张图片
    image.png
  • ❗️realizeClass初始化类,设置rw、ro
  • ❗️处理分类,将分类中的方法、协议、属性添加到宿主类中

回调函数load_images

  • ❗️该函数主要功能就是把需要执行+(void)load方法的类和分类分别添加进loadable_classesloadable_categories这俩个表中

你可能感兴趣的:(程序加载过程)