美文网首页
Main调用之前的加载过程

Main调用之前的加载过程

作者: 繁星mind | 来源:发表于2018-03-10 14:25 被阅读127次

    1.系统加载可执行文件(自身app的所有.o文件的集合)

    2.加载动态链接器dyld,dyld从可执行文件的以来开始,递归加载动态链接库

    3.动态链接库包括所有用到的framework,加载runtime的libobjc,系统libSystem,例如:GCD和block的库

    4.动态链接库的加载步骤具体分为5步:
    load dylibs image 读取库镜像文件
    Rebase image
    Bind image
    Objc setup
    initializers

    1)load dylibs image
    分析所依赖的动态库
    找到动态库的mach-o文件
    打开文件
    验证文件
    在系统核心注册文件签名
    对动态库的每一个segment调用mmap()

    2) rebase/bind
    rebase修复的是指向当前镜像内部的资源指针; 而bind指向的是镜像外部的资源指针。 rebase步骤先进行,需要把镜像读入内存,并以page为单位进行加密验证,保证不会被篡改,所以这一步的瓶颈在IO。bind在其后进行,由于要查询符号表,来指向跨镜像的资源,加上在rebase阶段,镜像已被读入和加密验证,所以这一步的瓶颈在于CPU计算。

    3)Objc setup
    注册Objc类 (class registration)
    把category的定义插入方法列表 (category registration)
    保证每一个selector唯一 (selctor uniquing)

    4.)initializers
    Objc的+load()函数
    C++的构造函数属性函数 形如attribute((constructor)) void DoSomeInitializationWork()
    非基本类型的C++静态全局变量的创建(通常是类或结构体)(non-trivial initializer) 比如一个全局静态结构体的构建,如果在构造函数中有繁重的工作,那么会拖慢启动速度

    load的加载过程:
    1)dyld 开始将程序二进制文件初始化
    2)交由 ImageLoader 读取 image,其中包含了我们的类、方法等各种符号
    3)由于 runtime 向 dyld 绑定了回调,当 image 加载到内存后,dyld 会通知 runtime 进行处理
    4)runtime 接手后调用 mapimages 做解析和处理,接下来 loadimages 中调用 callloadmethods 方法,遍历所有加载进来的 Class,按继承层级依次调用 Class 的 +load 方法和其 Category 的 +load 方法

    参考资料:
    https://techblog.toutiao.com/2017/01/17/iosspeed/
    https://blog.sunnyxx.com/2014/08/30/objc-pre-main/

    相关文章

      网友评论

          本文标题:Main调用之前的加载过程

          本文链接:https://www.haomeiwen.com/subject/dbhchxtx.html