alloc原理初探
-
[探索alloc的引入]
-
[alloc源码探索的三种方式]
-
[alloc做了什么事情]
-
[init做了什么事情]
-
[alloc的核心方法]
探索alloc的引入
LGPerson *p2 = [p1 init];
LGPerson *p3 = [p1 init];
NSLog(@"%@-%p-%p",p1,p1,&p1);
NSLog(@"%@-%p-%p",p2,p2,&p2);
NSLog(@"%@-%p-%p",p3,p3,&p3);
打印信息
**<LGPerson: 0x600000abc470>-0x600000abc470-0x7ffee2e850d8**
**<LGPerson: 0x600000abc470>-0x600000abc470-0x7ffee2e850d0**
**<LGPerson: 0x600000abc470>-0x600000abc470-0x7ffee2e850c8**
问题引入****3个不同地址指针同时指向同一片内存空间 alloc是不是开辟了内存 init是不是内存一样****
alloc源码探索的三种方式
1.下符号断点alloc直接跟流程
2.通过按住control - step into
3.通过汇编流程 ->查看源码出处。
**源码来源libobjc.A.dylib**
定位objc源码
苹果开源源码汇总: opensource.apple.com
这个地址用的更直接 opensource.apple.com/tarballs/
alloc流程图
源码分析
咋们下断点跟汇编
汇编实际开始是调用了objc_alloc 这里就引起了我们的思考,明明写的是alloc 为什么调用的确是objc_alloc
这里就不得不想到编译器LLVM给我们的代码做了相关的处理。
llvm下载地址:github.com/llvm/llvm-p…
大概意思就是给对象发送alloc消息LLVM会进行拦截判断是不是特殊的alloc方法如果是给发送的接受者标记并且把修改成调用objc_alloc->callAlloc->_objc_rootAllocWithZone
重新发送一次alloc消息
接下来流程如下看上面流程图
alloc做了什么事情?
1.计算成员变量所需要的字节大小并对齐
2.传入给calloc开辟类空间
3.类与isa绑定关联
一一分析
size = cls->instanceSize(extraBytes);
成员变量以8字节对齐
calloc我们下一章分析
obj->initInstanceIsa(cls, hasCxxDtor);
init底层做了什么
return _objc_rootInit(self);
}
_objc_rootInit(id obj)
{
return obj;
}
提供工厂方法初始化为开发人员提供一个构造方法的入口