NSObject的本质
typedef struct objc_class *Class;
struct NSObject_IMPL {
Class isa;
}
@interface NSObject{
Class isa;
}
- 一个NSObject对象占用多少内存?系统分配了16个字节给NSObject对象(通过malloc_size函数获得),但NSObject对象内部只使用了8个字节的空间(64bit环境下,可以通过class_getInsatnceSize函数)
NSObject *obj = [[NSObject alloc] init];
//获取NSObject实例对象的成员变量所占用的大小:8
NSLog(@"%zd",class_getInstanceSize([NSObject class]));
//获得obj指针所指向内存的大小:16
NSLog(@"%zd",malloc_size((__bridge const void *)(obj)));
Student的本质
struct NSObject_IMPL {
Class isa; //8
};
//底层转换
struct Student_IMPL {
struct NSObject_IMPL NSObject_IVARS;
int _no;//4
int _age;//4
};
@interface Student : NSObject
{
@public
int _no;
int _age;
}
@end
@implementation Student
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
Student *student = [[Student alloc] init];
//16
NSLog(@"%zd",malloc_size((__bridge const void *)(student)));
//16
NSLog(@"%zd",class_getInstanceSize([Student class]));
}
return 0;
}
更复杂的继承结构
struct NSObject_IMPL {
Class isa;
};
struct People_IMPL {
struct NSObject_IMPL NSObject_IVARS;//8
int _age;//4
};//16, 1:OC对象的占用内存至少16个字节 2:内存对齐:结构体的最终大小必须是最大成员大小的倍数 8 * 2 = 16
struct Student_IMPL {
struct People_IMPL People_IVARS;//16
int _no;//4
};//16
@interface People : NSObject
{
int _age;
}
@end
@implementation People
@end
@interface Student : People
{
@public
int _no;
}
@end
@implementation Student
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
//class_getInstanceSize:返回的是实例对象至少需要多少内存空间 mallocSize:返回系统实际分配内存的大小
People *people = [[People alloc] init];
NSLog(@"people *** mallocSize === %zd, instanceSize === %zd",malloc_size((__bridge const void *)(people)),class_getInstanceSize([People class])); // 16 16
Student *student = [[Student alloc] init];
NSLog(@"student *** mallocSize === %zd, instanceSize === %zd",malloc_size((__bridge const void *)(student)),class_getInstanceSize([Student class])); // 16 16
}
return 0;
}
alloc的size分析
struct NSObject_IMPL {
Class isa; //8
};
struct Person_IMPL {
struct NSObject_IMPL NSObject_IVARS; //8
int _age; //4
int _height; //4
int _no; //4
};//计算结构体大小,内存对齐原则:最终大小必须是结构体内最大成员大小的倍数,8 * 3 = 24
@interface Person: NSObject
{
int _age;
int _height;
int _no;
}
@end
@implementation Person
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *person = [[Person alloc] init];
//32 24 为啥mallocSize是32?根据层层源码研究,alloc->allocWitnZone->发现是calloc调用导致的->malloc_zone_calloc->结论:操作系统分配内存也有对齐的概念,Buckets sized {16, 32, 48, ..., 256},一般是16的倍数,所以24变为16的倍数,就是32了
NSLog(@"mallocSize = %zd, instanceSize = %zd",malloc_size((__bridge const void *)(person)),class_getInstanceSize([Person class]));
}
return 0;
}