iOS 应用程序加载

本文深入探讨了iOS应用的加载过程,包括动、静态库的区别与使用,以及APP启动时的加载步骤。从分析加载过程到运行所有初始化程序,详细解析了如何实例化主程序、加载动态库、执行初始化条件等关键环节,揭示了系统如何调用方法并通知进行镜像文件的初始化。
摘要由CSDN通过智能技术生成

1. APP 加载分析

1.1 动静态库
  1. app依赖很多底层库,底层库是很什么?

    可执行的代码的二进制,可以被操作系统写入到内存

  2. 库分为几种?
    静态库: .a .lib,动态库: framework .so .dll

  3. 动静态库的区别?

    静态库:在链接阶段,会将汇编生成的目标文件与引用的库一起链接打包到可执行文件中,可能会重复编译多次

    动态库:程序编译并不会链接到目标代码中,而是程序运行时才被载入。
    优势:减少打包之后APP的大小,共享内容,节约资源,通过更新动态库,达到更新程序的目的。
    常见动态库:UIKit,libdispatch、libobj.dyld

编译过程:

动静态库示例:

1.2 加载过程

2._dyld_start 分析

通过在+ (void)load方法中添断点,查看调用堆栈,通过汇编查看,在程序启动的时,调用dyldbootstrap::start(dyld3::MachOLoaded const*, int, char const**, dyld3::MachOLoaded const*, unsigned long*),那么在这之前还有一系列操作,


通过bt,查看调用堆栈

接下来我们分析一下_dyld_start,查看dyld源码,全局搜索_dyld_start,发现会跳转dyldbootstrap::start 方法,为c++方法,


全局搜索start(,找到start方法,

uintptr_t start(const struct macho_header* appsMachHeader, int argc, const char* argv[], 
				intptr_t slide, const struct macho_header* dyldsMachHeader,
				uintptr_t* startGlue)
{
	// if kernel had to slide dyld, we need to fix up load sensitive locations
	// we have to do this before using any global variables
    slide = slideOfMainExecutable(dyldsMachHeader);
    bool shouldRebase = slide != 0;
#if __has_feature(ptrauth_calls)
    shouldRebase = true;
#endif
    if ( shouldRebase ) {
        rebaseDyld(dyldsMachHeader, slide);
    }

	// allow dyld to use mach messaging
	mach_init();

	// kernel sets up env pointer to be just past end of agv array
	const char** envp = &argv[argc+1];
	
	// kernel sets up apple pointer to be just past end of envp array
	const char** apple = envp;
	while(*apple != NULL) { ++apple; }
	++apple;

	// set up random value for stack canary
	__guard_setup(apple);

#if DYL
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值