最近学习iOS的一些底层知识,有感自身基础知识匮乏,学习压力甚大,特制作文档预防脑容量不足导致信息丢失。
作为一名iOS的开发人员,对于对象的初始化想必用的是及其频繁的 就像这个
NSObject *obc = [[NSObject alloc] init];
想必大家对这个东西很熟悉吧,使用的很熟练吧,我之前也是这么认为的。然而在经过系统学习后才发现,原来自己根本就不了解他的实现。嗯,简单来说就是 我以为我看到了你的脸,但其实我只看到了你脸上厚厚的粉...
然而想要了解真相,那就要想办法去除其包装,才能看到它真实的面容。那么要怎样才能去伪求真呢——看源码实现。
1.对象存储查看:创建一个模型类 YPerson 继承于NSObject 初始化病分别打印 对象、对象地址、指向对象的指针地址:
YPerson *person = [YPerson alloc];
YPerson *person2 = [person init];
YPerson *person3 = [person init];
NSLog(@"%@---%p---%p",person,person,&person);
NSLog(@"%@---%p---%p",person2,person2,&person2);
NSLog(@"%@---%p---%p",person3,person3,&person3);
打印结果:
<YPerson: 0x600003654270>---0x600003654270---0x16d32fff8
<YPerson: 0x600003654270>---0x600003654270---0x16d32fff0
<YPerson: 0x600003654270>---0x600003654270---0x16d32ffe8
从打印结果可以看出在alloc之后无论是否执行init方法,执行几次,对象与对象地址都没有任何变化,而指针地址却按照8字节间隔依次向下递减。所以可以判断出指针地址是保存在栈内存中,而对象地址始终保持不变并且从打印地址来看地址头部为0x60,大致可以判断出对象地址在堆区域。(不要问我为什么,我也是听说的)
结果:alloc开辟内存空间, init暂未知
数年的开发经验,我居然都不知道alloc之后对象就创建好了😳,还一直以为只有init之后对象才创建好😱😱😱。幸好别人不知道我不知道😑。
2.代码实现探究:
想要查看源码实现最简单的操作就是按住command选择函数,但系统函数无法通过通过这种方式查看实现流程,所以需要使用其他的方法实现查看实现流程。可操作方法有:
①使用断点符号断住alloc 按住control键点击 step into 执行下一步,找到objc_alloc 并对其下符号断点
按照以下流程执行
不知道什么事 step into ? 看下面
② 显示汇编 xcode->Debug->Debug Workflow->Always Show Diassesmbly
完成此设置后,下断点会直接显示汇编内容,可以按照①中的方式断住alloc 点击step into 查找或直接下符号断点查找。
③直接对alloc下符号断点
断住alloc函数->添加符号断点 alloc->继续执行
下断点并运行程序
添加alloc 符号断点
继续执行
执行结果:
④下载源码库 创建demo查看代码执行流程
alloc 实现流程图:
关闭 Always Show Diassesmbly -> 断点断住alloc->点击Step into 进入alloc执行流程。
自己实际操作看到的流程:流程图
如有错误请指正