1. 一个NSObject对象占用多少内存?
系统分配16个字节给NSObject对象(通过malloc_size函数获取)
但是NSObject对象内部只使用了8个字节的存储空间(64bit环境下,通过class_getInstanceSize函数获取)
@interface MJPerson : NSObject
{
int _age;
int _height;
int _no;
}
@end
@implementation MJPerson
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
MJPerson *p = [[MJPerson alloc] init];
NSLog(@"%zd %zd",
class_getInstanceSize([MJPerson class]), // 24
malloc_size((__bridge const void *)(p))); // 32
}
return 0;
}
为何打印结果是 24 32 呢?
class 的isa指针需要占据8个字节, 3个int需要占据12字节,一共20字节,申请内存的时候有个内存对齐原则,基本单位是8,所以申请了24字节的内存;
但是系统实际分配内存的时候,也有对齐原则,基本单位是16,所以实际上系统给这个类分配了32字节的内存
2.OC中对象分哪几种?它们在内存中分别存储着什么信息?
OC中的对象主要有以下3种
- instance 对象 (实例对象)
- class对象(类对象)
- meta-class对象(元类对象)
instance对象在内存中存储的信息
isa指针
其他成员变量
class对象在内存中存储的信息有:
isa指针
superclass指针
类的属性信息(@property) . 类的实例方法信息. 类的协议信息
meta-class对象在内存中存储的信息有
isa指针
superclass指针
类的类方法信息
3.对象的isa指向哪里?
在OC中任何对类的定义都可以看成是一个对象,而每一个对象必定都包含一个isa指针
instance的isa指向class
class的isa指向meta-class
mete-class的isa指向基类的meta-class
延伸1:
1. instance方法的调用轨迹
isa找到class,方法存在,直接调用;方法不存在,通过superclass找父类…
2. class方法的调用轨迹
isa找到meta-class,方法存在,直接调用;方法不存在,就通过superclass找父类…
延伸2:
通过instance的isa指针找到类对象的地址,从64bit开始,需要进行一次位运算,才能找到真正的类地址