XB_OC对象的本质

1.对象简介

OC对象是基于C/C++的结构体实现的,可以用以下命令把OC文件转换成CPP文件,这样可以看到OC对象的结构体样式

xcrun  -sdk  iphoneos  clang  -arch  arm64  -rewrite-objc  OC源文件  -o  输出的CPP文件

以下都是基于64位环境

//OC样式的
@interface NSObject{
//实际上隐藏着一个指针
  Class isa;//指针8字节
}
@end
//结构体样式的
struct NSObject_IMPL{
  Class isa;//指针8字节
}

//Class实际上是一个结构体指针
typedef struct objc_class *Class;

从这里可以看到,isa指针的地址其实就是指向初始化实例对象的指针的地址,类似于数组第一个元素的地址实际上就是整个数组的地址。

2.对象内存分布

1.一个isa指针占用8个字节,理论上说没有成员变量的对象应该就是8个字节,但是它底层有个限制,一个对象如果小于16字节,便让该对象等于16字节。

2.如果添加一个int类型的成员变量呢

//OC样式的
@interface NSObject{
   @public
//实际上隐藏着一个指针
  Class isa;//指针8字节
  int _no;//4字节
}
@end
//结构体样式的
struct NSObject_IMPL{
  Class isa;//指针8字节
  int _no;//4字节
}

这么看应该是12字节,其实应该还是16字节,分配的16字节那个isa指针只用了8字节,还有8字节空着呢。

3.如果继承了某个类呢

/*NSObject*/
//OC样式的
@interface NSObject{               
   @public
//实际上隐藏着一个指针                  
  Class isa;//指针8字节
}
@end

//结构体样式的
struct NSObject_IMPL{
  Class isa;//指针8字节
}
/*------------------------------Person------------------------------------*/

//OC样式的
@interface Person{               
  int _age;//4字节
}
@end

//结构体样式的
struct Person_IMPL{
  strcut NSObject_IMPL NSObject_IVARS;//16字节
  int _age;//4字节
}
/*------------------------------Student------------------------------------*/
//OC样式的
@interface Student{               
  int _no;//4字节
}
@end

//结构体样式的
struct Student_IMPL{
  strcut Person_IMPL Person_IVARS;
  int _no;//4字节
}

其实Student与Person的内存都是16字节,首先一个空对象分配有16字节,isa占8字节,在Person中的age占4字节,还没有占完,在Student中的no占4字节,正好占完整个16字节。

有点类似于这样


//OC样式的
@interface Student{     
  Class isa;//指针8字节   
  int _age;//4字节       
  int _no;//4字节
}
@end

//结构体样式的
struct Student_IMPL{
   Class isa;//指针8字节   
  int _age;//4字节       
  int _no;//4字节
}

4.查看内存

创建一个实例对象至少需要多少内存(是根据结构体内存对齐之后的大小)

#import <objc/runtime.h>

class_getInstanceSize([NSObject class]);

创建一个实例对象实际上分配了多少内存(是根据内存块对齐分配的,底层有个Buckets sized{16,32,48,64,80,96,112....},会根据结构体对齐之后的内存分配一个合适的16的倍数的内存块)

#import <malloc/malloc.h>

malloc_size((__bridge const void *)obj);

关于这两个的区别,例如

//OC样式的
@interface Student{     
  Class isa;//指针8字节   
  int _age;//4字节       
  int _no;//4字节
  int _name;//4字节
}
@end

//结构体样式的
struct Student_IMPL{
   Class isa;//指针8字节   
  int _age;//4字节       
  int _no;//4字节
  int _name;//4字节
}//结构体内存对齐之后需要24字节

这里class_getInstanceSize的结果是24,但是它不是16的倍数,所以malloc_size是32

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值