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


app启动

上图中image是镜像文件
dyld加载过程
- _dyld_start 连接开始
- uInptr_start(...)应用程序进来 dyld::_main
- 2.1 环境变量相关处理
- 2.2 加载共享缓存
- 2.3 将dlyd本身添加到UUID列表
- 2.4 reloadAllImages
- 2.4.1实例化主程序
- 2.4.2加载任何插入动态库
- 2.4.3连接库
- 2.5 运行所有初始化程序
- 2.6 通知监听dlyd的main
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);
}

环境变量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中的具体内容;如下


然后重新跑一遍程序,查看打印。你可以看到所有load的方法

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

map_Images
Load_Images
总结
APP启动过程
- APP启动
- 加载libSystem
- Runtime向dyld注册回调函数
- 加载新的image
- 执行map_images、load_images
- 调用main函数
网友评论