概述
我们在这样alloc
一个对象时oc
底层究竟做了啥 QHPerson *p = [QHPerson alloc] ;
要想分析我们必须先拿到objc的源码,当然也有其他的方式,比如符号断点、汇编等,但是源码分析最直接。
苹果源码官网,下载后可以编译一下objc源码,这里不讲述如何编译
oc alloc 流程图
先来一份总结的oc alloc流程图
alloc 流程图.png
源码分析
第一步:NSObject 里面会调用
+ (id)alloc {
return _objc_rootAlloc(self);
}
第二步:这里有一个objc
版本的判断,但是不影响主流程
callAlloc(Class cls, bool checkNil, bool allocWithZone=false)
{
#if __OBJC2__
if (slowpath(checkNil && !cls)) return nil;
if (fastpath(!cls->ISA()->hasCustomAWZ())) {
return _objc_rootAllocWithZone(cls, nil);
}
#endif
// No shortcuts available.
if (allocWithZone) {
return ((id(*)(id, SEL, struct _NSZone *))objc_msgSend)(cls, @selector(allocWithZone:), nil);
}
return ((id(*)(id, SEL))objc_msgSend)(cls, @selector(alloc));
}
第三步:创建实例
...
//计算实例要分配的内存大小,里面有一个算法,oc对象最少时16字节,8的倍数。也就是16 、24、32 ...
size = cls->instanceSize(extraBytes);
if (outAllocatedSize) *outAllocatedSize = size;
//调用c语音calloc开辟空间
id obj;
if (zone) {
obj = (id)malloc_zone_calloc((malloc_zone_t *)zone, 1, size);
} else {
obj = (id)calloc(1, size);
}
//实例对象关联类
if (!zone && fast) {
obj->initInstanceIsa(cls, hasCxxDtor);
} else {
// Use raw pointer isa on the assumption that they might be
// doing something weird with the zone or RR.
obj->initIsa(cls);
}