一、 iOS 程序 main 函数之前发生了什么?
https://blog.sunnyxx.com/2014/08/30/objc-pre-main/
- 动态链接库
静态链接的代码在编译的时候就已经链接到程序中,运行时直接执行二进制文件;而动态链接库需要在程序启动后才会动态去链接这些动态库,这就是为什么在倒入动态库的时候我们会去设置 link binary with Libraries 选项。
有两个默认添加的 lib:libobjc 即 objc 和 runtime,libSystem 中包含了很多系统级别 lib,列几个熟知的:
libdispatch ( GCD )
libsystem_c ( C语言库 )
libsystem_blocks ( Block )
libcommonCrypto ( 加密库,比如常用的 md5 函数 )
这些 lib 都是dylib格式(如 windows 中的 dll ),系统使用动态链接有几点好处:
- 代码共用:很多程序都动态链接了这些 lib,但它们在内存和磁盘中只有一份
- 易于维护:由于被依赖的 lib 是程序执行时才 link 的,所以这些 lib 很容易做更新,比如libSystem.dylib 是 libSystem.B.dylib 的替身,哪天想升级直接换成 libSystem.C.dylib 然后再替换替身就行了
- 减少可执行文件体积:相比静态链接,动态链接在编译时不需要打进去,所以可执行文件的体积要小很多
- dyld
dyld(the dynamic link editor),Apple 的动态链接器,系统 kernel 做好启动程序的初始准备后,交给 dyld 负责,援引并翻译《 Mike Ash 这篇 blog 》对 dyld 作用顺序的概括:
- 从 kernel 留下的原始调用栈引导和启动自己
- 将程序依赖的动态链接库递归加载进内存,当然这里有缓存机制
- non-lazy 符号立即 link 到可执行文件,lazy 的存表里
- Runs static initializers for the executable
- 找到可执行文件的 main 函数,准备参数并调用
- 程序执行中负责绑定 lazy 符号、提供 runtime dynamic loading services、提供调试器接口
- 程序main函数 return 后执行 static terminator
- 某些场景下 main 函数结束后调 libSystem 的 _exit 函数
二、Objective-C +load vs +initialize
http://blog.leichunfeng.com/blog/2015/05/02/objective-c-plus-load-vs-plus-initialize/
- +load方法
- 在加载类的时候被调用
- iOS应用启动的时候,回加载所有的类,就会调用每个类的这个方法
- 在mian函数之前每调用
三、 Objective-C Autorelease Pool 的实现原理
http://blog.leichunfeng.com/blog/2015/05/31/objective-c-autorelease-pool-implementation-principle/
https://blog.sunnyxx.com/2014/10/15/behind-autorelease/
四、 iOS自动布局框架 - Masonry详解
https://www.jianshu.com/p/ea74b230c70d
五、 深入理解RunLoop
https://blog.ibireme.com/2015/05/18/runloop/
六、 iOS中__block 关键字的底层实现原理
七、 堆栈
https://www.jianshu.com/p/746c747e7e00
八、大小端模式
为什么会有大小端模式之分呢?这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为 8bit。但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的long型(要看具体的编译器),另外,对于位数大于 8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。例如一个16bit的short型x,在内存中的地址为0x0010,x的值为0x1122,那么0x11为高字节,0x22为低字节。对于 大端模式,就将0x11放在低地址中,即0x0010中,0x22放在高地址中,即0x0011中。小端模式,刚好相反。我们常用的X86结构是小端模式,而KEIL C51则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以随时在程序中(在ARM Cortex 系列使用REV、REV16、REVSH指令 [1] )进行大小端的切换。
大端模式:数据的高字节存放在低地址中,数据的低字节存放在高地址中
小端模式:数据的低字节存放的高地址中,数据的高字节存放在低地址中