美文网首页
iOS oc对象的本质

iOS oc对象的本质

作者: nickNic | 来源:发表于2021-04-08 16:56 被阅读0次
   NSObject *obj = [[NSObject alloc]init];
 
   获取obj指针所指向内存的大小
   NSLog(@"%zd",malloc_size((__bridge const void *)(obj)));  打印得出结果为16
   通过查看苹果源码得知苹果默认给NSObject 分配16个字节 如果小于16也就将默认值赋给它
   iOS创建对象都是以16的倍数内存对齐

   16的由来查看苹果源码得知 
    inline 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.
    if (size < 16) size = 16;
    return size;
}







   获取NSObject实例对象的成员变量所占用的大小
   NSLog(@"%zd",class_getInstanceSize([NSObject class]));打印得出结果为8

   
   通过查看苹果源码得知 class_getInstanceSize底层实现
  size_t class_getInstanceSize(Class cls)
  {
    if (!cls) return 0;
    return cls->alignedInstanceSize();
  }
     // Class's ivar size rounded up to a pointer-size boundary.  返回实例对象的成员变量所占用的大小
   uint32_t alignedInstanceSize() const {
        return word_align(unalignedInstanceSize());
   }


   接下来可以查看NSObject的定义
   @interface NSObject <NSObject> {
        Class isa ;
   }
   因为NSObject第一个成员变量就是isa  类型为指针 默认占8字节
   // 上述代码NSObject底层实现代码
   struct NSObject_IMPL{
      Class  isa;
   }
   点击 Class isa 可以查看到是 typedef struct objc_class *Class; 类型
   返回是个结构体指针  而结构体也就这么一个成员 所以也就证明了为什么   
   NSLog(@"%zd",class_getInstanceSize([NSObject class]));打印得出结果为8  指针在64位环境下占8个字节

   class_getInstanceSize是实例对象需要多少存储空间。 malloc_size 是给了实例对象多少存储空间也就是实际分配的存储空间
   malloc_size的值 =  class_getInstanceSize的值+16的倍数
   如果打印 class_getInstanceSize = 24  
   那么 malloc_size 就= 32;因为24以大于16但为了内存对齐所以会取16的倍数也就是32
  
   class_getInstanceSize成员变量只有3个int型的话打印出的值会=24 也许有人会问不是20么 3*4 =12; 
   12 + 8 = 20才对啊 
   其实  class_getInstanceSize也会以最大的倍数8 内存对齐来取值 8的由来便是isa指针的值 

综上所述得知系统分配了16个字节给NSObject 对象 但NSObject对象内部只用了8个字节的空间来装isa
(在64位的环境下)

相关文章

网友评论

      本文标题:iOS oc对象的本质

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