iOS OC对象alloc流程

2021-02-28  本文已影响0人  kaijiemu

一,苹果开源源码汇总: https://opensource.apple.com

    这个地址用的更直接 https://opensource.apple.com/tarballs/

二,下载最新的objc源码,找到_class_createInstanceFromZone方法,就是alloc主要做的事情


_class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone,

                              intconstruct_flags =OBJECT_CONSTRUCT_NONE,

                              boolcxxConstruct =true,

                              size_t*outAllocatedSize =nil)

{

    ASSERT(cls->isRealized());

    // Read class's info bits all at once for performance

    boolhasCxxCtor = cxxConstruct && cls->hasCxxCtor();

    boolhasCxxDtor = cls->hasCxxDtor();

    boolfast = cls->canAllocNonpointer();

    size_tsize;

    //1,计算对象需要分配多少空间

    size = cls->instanceSize(extraBytes);

    if(outAllocatedSize) *outAllocatedSize = size;

    idobj;

    if(zone) {

        obj = (id)malloc_zone_calloc((malloc_zone_t*)zone,1, size);

    }else{

        // 2,alloc 向系统申请开辟内存的地方,返回地址指针

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

    }

    if(slowpath(!obj)) {

        if(construct_flags &OBJECT_CONSTRUCT_CALL_BADALLOC) {

            return _objc_callBadAllocHandler(cls);

        }

        returnnil;

    }

    if(!zone && fast) {

        //3,关联到相应的类

        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)) {

        returnobj;

    }

    construct_flags |=OBJECT_CONSTRUCT_FREE_ONFAILURE;

    returnobject_cxxConstructFromClass(obj, cls, construct_flags);

}

三,alloc 底层主要做了3件事情

1,计算对象需要分配多少空间,16字节对齐

     cls->instanceSize(extraBytes)
size_t instanceSize(size_t extraBytes) const {
        if (fastpath(cache.hasFastInstanceSize(extraBytes))) {
            return cache.fastInstanceSize(extraBytes);
        }

        size_t size = alignedInstanceSize() + extraBytes;
        // CF requires all objects be at least 16 bytes.
        // 16字节对齐,不够16字节,默认给16字节
        if (size < 16) size = 16;
        return size;
    }
size_t fastInstanceSize(size_t extra) const
    {
        ASSERT(hasFastInstanceSize(extra));

        if (__builtin_constant_p(extra) && extra == 0) {
            return _flags & FAST_CACHE_ALLOC_MASK16;
        } else {
            size_t size = _flags & FAST_CACHE_ALLOC_MASK;
            // remove the FAST_CACHE_ALLOC_DELTA16 that was added
            // by setFastInstanceSize
            return align16(size + extra - FAST_CACHE_ALLOC_DELTA16);
        }
    }

这个函数是16字节对齐的算法,x + 15 与上 15取反
例如:x = 12, 12 + 15 = 27
0000 1100 :12
0000 1111 : 15
0001 1011 := 27
1111 0000 :与15取反
0001 0000 := 16

static inline size_t align16(size_t x) {
    return (x + size_t(15)) & ~size_t(15);
}

2,向系统申请开辟内存,返回地址指针

   calloc

3,关联到相应的类

    obj->initInstanceIsa

四,init 其实只是返回 (id)self

init : return (id)self; 是一个构造方法,一种工厂设计模式

上一篇下一篇

猜你喜欢

热点阅读