美文网首页
iOS OC对象alloc流程

iOS OC对象alloc流程

作者: kaijiemu | 来源:发表于2021-02-28 00:07 被阅读0次

    一,苹果开源源码汇总: 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; 是一个构造方法,一种工厂设计模式

    相关文章

      网友评论

          本文标题:iOS OC对象alloc流程

          本文链接:https://www.haomeiwen.com/subject/rmpwfltx.html