1、alloc 探索---查找alloc源码所在位置sass
先给出一段代码
复制代码
LGPerson *p1 = [LGPerson alloc];
LGPerson *p2 = [p1 init];
LGPerson *p3 = [p1 init];
LGNSLog(@"%@ - %p",p1,&p1);
LGNSLog(@"%@ - %p",p1,&p2);
LGNSLog(@"%@ - %p",p1,&p3);
复制代码
打印结果:bash
<LGPerson: 0x6000016c6260> - 0x7ffee49c8178app
<LGPerson: 0x6000016c6260> - 0x7ffee49c8170post
<LGPerson: 0x6000016c6260> - 0x7ffee49c8168spa
从结果能够总结为,p1,p2,p3 指向同一个内存空间,但建立出来的三个对象的指针地址是不一样的。设计
以此咱们可能就会产生以下几个疑问:3d
一、为何会出现这个打印结果呢?指针
由于 alloc 建立实例对象的同时也申请了一块内存空间,p1,p2,p3是分配的3个对象的指针,所以 p1,p2,p3 属于同一个对象并都指向这块内存空间。调试
二、alloc 又是怎么实现的呢?code
咱们经过分析alloc源码来寻找这个问题的答案,有以下三种方式来知道alloc源码所在的动态库,libobjc.A.dylib:
1)第一种方式:真机调试,打断点
在如图所示打上断点,而后按住 ‘control’的同时点击箭头所指的按钮进入,再继续点击此按钮,直到出现 libobjc.A.dylib
2)第二种方式:选择Symbolic Breakpoint ,在Symbol这栏输入 alloc 也能获得想要的答案。
而后出现不少不少实现了alloc方法的断点,再次真机运行
3)第三种方法:经过汇编 选择->Debug->Debug Workflow -> Always Show Disassembly,再次在真机上运行,此时会直接跳转到汇编界面
一直按直到出现以下图所示,出现alloc所在的动态库名
三、建立对象的过程当中与init的关系是什么呢?
2、alloc探索---下载并配置alloc所在的动态库开源的源码(objc)
源码下载地址:opensource.apple.com/tarballs/
3、alloc探索--分析查看 alloc 源码流程
1)alloc 流程图
部分源码解释
calloc : 申请对象和开辟内存空间
initInstanceIsa :关联内存指针
2)申请内存空间(字节对齐)
a.对象内存空间规则 8 字节对齐(目的:提升 cpu 读取速度,以空间换取时间)
b.内存所占空间小于16字节时,最少16字节,为了防止读取或存储时越界
查看内存空间结构:
打印指令:
x [对象名] :查看对象的存储空间,以16进制打印内存空间
x/[n]xg [对象名] : 以16 进制读取 n 个内存段
register read :读寄存器
随记:
x0:是第一个参数的传递者,也是返回值存储的地方(isa)
iOS 属于小端模式,内存地址倒着读