一、alloc方法在底层的调用流程
1.我们可以进入汇编语言进行探索(Debug-Debug Workflow-always Show Disasembly)
汇编指令:b/bl:跳转指令、 ret:函数返回、 ;(分号) :注释
alloc - objc_alloc - objc_magSend - alloc - _objc_rootAlloc - _objc_rootAllocWithZone
我们先从创建一个类开始,设置了汇编之后,运行项目直接进入汇编,一步一步进行后
此处验证了objc_alloc是LGPerson调起来的,这里通过objc_msgSend调用alloc方法
通过_objc_rootAllocWithZone,我们进入源码中看到,_objc_rootAllocWithZone方法中返回内容
返回的是obj
验证得到的是LGPerson
以上得出,当我们的类是继承NSObject的时候,创建对象的时候直接调用alloc方法就可以了
2.通过源码探索alloc的调用流程
当我们调用alloc方法的时候
以上得出的流程与汇编流程一致
为什么没有掉rootalloc,因为系统内部调用了fixupMessageRef方法,后面会详细说
二、编译器的优化等级
等级越高,没用到的值就不会调用
三、对象的本质
objc_object结构体,里面存储ISA指针和成员变量
四、字节对齐(以空间换时间,cpu读取效率更高)
每个对象都会有一个ISA,ISA就会占8字节,所以每个对象最少占8字节,如果连续的两块内存都是没有属性的对象,那么它们的内存空间就会完全的挨在⼀起,是容易混乱的。以16字节为⼀块,这就保证了CPU在读取的时候,按照块读取就可以,效率更⾼,同时还不容易混乱
五、结构体的内存对齐
1.数据成员对⻬规则:结构(struct)的第⼀个数据成员放在offset为0的地⽅,以后每个数据成 员存储的起始位置要从该成员⼤⼩或者成员的⼦成员⼤⼩的整数倍开始(⽐如int为4字节,则要 从4的整数倍地址开始存储)。
2.结构体作为成员:如果⼀个结构⾥有某些结构体成员,则结构体成员要从其内部最⼤元素⼤⼩的整 数倍地址开始存储.(struct a⾥存有struct b,b⾥有char,int ,double等元素,那b应该 从8的整数倍开始存储)
3.收尾⼯作:结构体的总⼤⼩,也就是sizeof的结果必须是其内部最⼤成员的整数倍,不⾜的要补 ⻬