美文网首页
iOS进阶——OC对象本质

iOS进阶——OC对象本质

作者: 风雨彩虹_123 | 来源:发表于2020-01-14 19:57 被阅读0次

    前言

    OC是面向对象语言,那我们在创建一个对象后,可以为对象赋值,储存等一系列的操作,那我们为什么可以这么操作?系统在背后偷偷的帮我们干了什么事?

    创建一个对象

       //创建一个对象  (alloc 为对象分配了内存  init为对象初始话)
        //实事如此吗?
        //Person *p = [[Person alloc]init];
        Person *p = [Person alloc];
        //给对象的一个属性赋值
        p.age = 10;
        //2020-01-14 17:35:08.450074+0800 ceshituisong[1778:1097651] 打印出age:10
        NSLog(@"打印出age:%d",p.age);
    

    从上面的测试结果看来,alloc后系统就给对象分配了内存和初始化。那么init到底做了什么吗?alloc在底层到底是怎么实现的?

    分析objc4_750源码

    源码下载地址
    在源码中我们发现init方法什么也没有做,只是返回了自己本身。

    + (id)init {
        return (id)self;
    }
    - (id)init {
        return _objc_rootInit(self);
    }
    
    id _objc_rootInit(id obj)
    {
        // In practice, it will be hard to rely on this function.
        // Many classes do not properly chain -init calls.
        return obj;
    }
    

    在源码中我们发现alloc在系统底层调用方法的顺序是:+ (id)alloc ->id
    _objc_rootAlloc(Class cls) -> static ALWAYS_INLINE id
    callAlloc(Class cls, bool checkNil, bool allocWithZone=false) ->id
    class_createInstance(Class cls, size_t extraBytes) ->id
    _class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone, bool cxxConstruct = true, size_t *outAllocatedSize = nil)

    下面对最后一个方向进行分析,看看系统是怎样创建对象的。下面是源码,已经将不重要的代码删除。

    static __attribute__((always_inline)) 
    id _class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone, bool cxxConstruct = true,  size_t *outAllocatedSize = nil)
    {
       //计算对象需要的内存空间
        size_t size = cls->instanceSize(extraBytes);
        id obj;
        if (!zone  &&  fast) {
            // 进行分配内存空间
            obj = (id)calloc(1, size);
            if (!obj) return nil;
            //进行创建对象
            obj->initInstanceIsa(cls, hasCxxDtor);
        } 
        //返回对象
        return obj;
    }
    
    size_t instanceSize(size_t extraBytes) {
          //字节对齐(兼容硬件   效率  iOS是8字节对齐) 空间换时间
          size_t size = alignedInstanceSize() + extraBytes;
          // CF requires all objects be at least 16 bytes.
          if (size < 16) size = 16;
          return size;
     }
    

    相关文章

      网友评论

          本文标题:iOS进阶——OC对象本质

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