一.OC对象的初始化
结果:
alloc有了内存,有了指针的指向,init不会对内存指针进行操作。
对代码进行修改如下:
可以看到打印结果如下:
可得alloc出来一片内存空间,p1,p2,p3为3个指针地址同时指向同一片内存空间,但地址是在栈里面,在栈中是连续的指针,相隔8字节。
1.alloc怎么做到的呢,init有什么用?
- 三种分析方法 (1)断点跟踪法 ibobjc.A.dylib`objc_alloc:
在代码中打断点
运行后在断点处停顿,
进入到
然后利用添加symbolic Breakpoint来进入底层源码
(2)debug汇编法 objc_alloc
进入X86底层汇编
继续断点到
(3)已知符号断点法 libobjc.A.dylib`+[NSObject alloc]:
然后断点下一步可进入
- open source (1)首先进入到alloc函数的源码
(2)在alloc源码中,再进入到_objc_rootAlloc中,可以看到
(3)同样的操作我们进入到callAlloc方法中
这里出现了分叉,为了分析到底走什么方法,则将以上流程都下好相应的符号断点,
但还不能直接运行,
register read x0会报错因为我们研究的是子类而不是父类,需要先运行到LGPerson的断点区域然后再打开运行断点
- 底层方法的编译和调试
编译器优化 arm64中,x代表64位, w代表32位 执行一个函数,结果放在x0位置也就是第一个参数的位置
这就是编译器优化
对象内存的大小由什么决定:成员变量 class isa为8,其为结构体指针类型,objc_class继承自objc_object if(size<16) size =16 字节对齐算法 (X+WORD_MASK)& ~WORD_MASK 8字节对齐,取8的整数
- alloc流程图
一个自定义类alloc的过程:
通过调用objc_alloc->callAlloc,在callAlloc内部分有缓存无缓存两种情况,
(1)当有缓存时:通过 _objc_rootAllocWithZone -> _class_createInstanceFromZone -> instanceSize -> calloc -> initInstanceIsa
(2)无缓存时:callAlloc内部通过objc_msgSend 调用alloc方法, 在alloc方法内部执行 _objc_rootAlloc -> callAlloc,后面步骤与上相同。