OC 对象 alloc流程

概述

我们在这样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);
    }

你可能感兴趣的:(OC 对象 alloc流程)