iOS底层收集

OC底层原理探索-07应用程序加载

2020-02-17  本文已影响0人  ricefun

app加载分析

我们知道app加载其实是依赖许多的底层库的,库是可执行的代码的而二进制文件,当加载的时候就会被操作系统写入到内存中。库分为静态库(.a、.lib)动态库(framework)

静态库和动态库区别

首先我们看一下编译过程图


编译过程 而动静态库的区别在于他们被编译的顺序 静动态库编译顺序 静态库会被多次编译,而动态库可以做到按需编译,所以动态库可以减少程序在打包后app的体积(占用的内存大小),共享了内存,节约内存资源(eg:UIKit、CoreFoundation、libObjc...)
app启动
app启动过程图

上图中image是镜像文件

dyld加载过程

void _objc_init(void)

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();
    tls_init();
    static_init();
    lock_init();
    exception_init();
    // 保存 - libobjc - dyld
    // C++ 怎么去做到通知
    // 指针 - 回调 - 函数的地址
    
    // 这里就是我们的数据 - images  - objc lib
    // dyld
    _dyld_objc_notify_register(&map_images, load_images, unmap_image);
}
截屏2020-02-1812.09.54.png
环境变量enviro_init();
void environ_init(void) 
{
    if (issetugid()) {
        // All environment variables are silently ignored when setuid or setgid
        // This includes OBJC_HELP and OBJC_PRINT_OPTIONS themselves.
        return;
    } 
   ...
   ...

        for (size_t i = 0; i < sizeof(Settings)/sizeof(Settings[0]); i++) {
            const option_t *opt = &Settings[i];            
           // if (PrintHelp) _objc_inform("%s: %s", opt->env, opt->help);
           //去掉if (PrintHelp)打印判断,可以看到好多环境变量
            _objc_inform("%s: %s", opt->env, opt->help);
            if (PrintOptions && *opt->var) _objc_inform("%s is set", opt->env);
        }
    }
}

注销上面标注的代码进行打印,可以看到lldb中的具体内容;如下


环境变量命遍历打印 这里的environ_init()函数负责环境的初始化,里面可以打印我们日常需要的调试数据,eg:OBJC_PRINT_LOAD_METHODS;那么如何使用呢?打开editScheme - 在debug模式下选择Arguments - 点击+号添加:OBJC_PRINT_LOAD_METHODS选择YES:如下图
然后重新跑一遍程序,查看打印。你可以看到所有load的方法

map_Images&Load_Images

将在下一章详细探究map_Images&Load_Images

截屏2020-02-1720.04.01.png
map_Images
Load_Images

总结

APP启动过程

上一篇下一篇

猜你喜欢

热点阅读