OC之alloc底层原理

1,285 阅读2分钟

OC底层原码下载

我们知道,iOS的OC底层代码实现是不开源的,我们要想研究其底层的实现原理,就得去Apple open source下载开源的代码。下载地址如下:

搜索"objc",并选择其中一个版本下载

探索alloc的底层原理实现

全局搜索"alloc {"

这里我们找到了"NSObject"的alloc类方法的实现,然后我们就可以一步一步的跟进去查看底层的实现并分析原理了

alloc

+ (id)alloc {
    return _objc_rootAlloc(self);
}

调用了_objc_rootAlloc函数,并将当前类对象作为参数传递进去

_objc_rootAlloc

id
_objc_rootAlloc(Class cls)
{
    return callAlloc(cls, false/*checkNil*/, true/*allocWithZone*/);
}

调用了callAlloc函数,将类对象传递进去

callAlloc

static ALWAYS_INLINE id
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));
}

主要调用了两个函数,_objc_rootAllocWithZone和objc_msgSend,我们只分析_objc_rootAllocWithZone;objc_msgSend很简单,不用多说。

_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函数

_class_createInstanceFromZone

这里面调用了3个核心的函数:instanceSize、calloc、initInstanceIsa,这三个函数分别是干什么的呢?

instanceSize

这个函数的返回值是一个size_t的数据,在calloc函数中会用到这个返回值。即请求开辟的内存空间大小,并且开辟的空间大小不小于16。而且调用的了alignedInstanceSize函数来进行字节对齐。即开辟的内存空间大小一定是16字节的整数倍。

calloc

obj = (id)calloc(1, size);

calloc是c语言的函数,表示分配1个size大小的内存空间

initInstanceIsa

inline void 
objc_object::initInstanceIsa(Class cls, bool hasCxxDtor)
{
    ASSERT(!cls->instancesRequireRawIsa());
    ASSERT(hasCxxDtor == cls->hasCxxDtor());

    initIsa(cls, true, hasCxxDtor);
}

此函数的作用是将calloc分配的内存和返回的指针地址与类对象进行关联

alloc流程总结