alloc内部到底做了什么?一般都知道开辟内存创建实例。
先看源码:经过查看多个文章发现objc的alloc方法一直也在优化。
先贴几个我查找的文章:
http://www.cocoachina.com/articles/29200
https://blog.csdn.net/u014600626/article/details/86714085
当前文章介绍版本是objc4-787.1版本(2020年12月01日最新)
先贴一个我根据源码花的流程图(如有不对欢迎指正)
相关源码
alloc实现
+ (id)alloc {
return _objc_rootAlloc(self);
}
_objc_rootAlloc 🔽
id
_objc_rootAlloc(Class cls)
{
return callAlloc(cls, false/*checkNil*/, true/*allocWithZone*/);
}
callAlloc🔽
static ALWAYS_INLINE id
callAlloc(Class cls, bool checkNil, bool allocWithZone=false)
{
#if __OBJC2__
if (slowpath(checkNil && !cls)) return nil;// cls 为空返回
if (fastpath(!cls->ISA()->hasCustomAWZ())) { // 如果 cls 没有实现自定义 allocWithZone 方法
return _objc_rootAllocWithZone(cls, nil); // 调用 _objc_rootAllocWithZone
}
#endif
// No shortcuts available.
if (allocWithZone) { // 如果 allocWithZone 为 true,调用 allocWithZone 创建对象
return ((id(*)(id, SEL, struct _NSZone *))objc_msgSend)(cls, @selector(allocWithZone:), nil);
}
return ((id(*)(id, SEL))objc_msgSend)(cls, @selector(alloc));// 否则调用 alloc 方法创建对象
}
查看上面文章这个方法做了优化,开辟内存的代码移到了_class_createInstanceFromZone方法
_objc_rootAllocWithZone🔽
id
_objc_rootAllocWithZone(Class cls, malloc_zone_t *zone __unused)
{
// allocWithZone under __OBJC2__ ignores the zone parameter
return _class_createInstanceFromZone(cls, 0, nil,
OBJECT_CONSTRUCT_CALL_BADALLOC);
}
_class_createInstanceFromZone 开辟内存创建实例🔽
static ALWAYS_INLINE id
_class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone,
int construct_flags = OBJECT_CONSTRUCT_NONE,
bool cxxConstruct = true,
size_t *outAllocatedSize = nil)
{
ASSERT(cls->isRealized());
// 同时读取类的所有信息以提高性能
bool hasCxxCtor = cxxConstruct && cls->hasCxxCtor();
bool hasCxxDtor = cls->hasCxxDtor();
bool fast = cls->canAllocNonpointer();
size_t size;
// 计算需要的空间大小
size = cls->instanceSize(extraBytes);
if (outAllocatedSize) *outAllocatedSize = size;
id obj;
if (zone) {// 申请内存
obj = (id)malloc_zone_calloc((malloc_zone_t *)zone, 1, size);
} else {
obj = (id)calloc(1, size);
}
if (slowpath(!obj)) {// 返回错误信息
if (construct_flags & OBJECT_CONSTRUCT_CALL_BADALLOC) {
return _objc_callBadAllocHandler(cls);
}
return nil;
}
// 创建isa指针
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);
}
if (fastpath(!hasCxxCtor)) {
return obj;
}
construct_flags |= OBJECT_CONSTRUCT_FREE_ONFAILURE;
return object_cxxConstructFromClass(obj, cls, construct_flags);
}
看之前的文章,在callAlloc中就申请内存空间创建isa,返回对象。到这个版本苹果将申请内存和创建isa的代码抽离,还做了好多的优化,所以说苹果的代码在不断优化中。不是有了Swift就不要OC了。