OC对象本质是一个结构体
通过 clang -rewrite-objc main.m -o main.cpp 编译为C++代码可以看出
struct NSObject_IMPL {
Class isa;
};
可以看出一个NSObject对象实际上是NSObject_IMPL结构体,内部只有一个isa指针变量。
OC对象大小
@interface Persion : NSObject
{
@public
int _height;
}
@end
@implementation Persion
@end
@interface Student : Persion
{
@public
int _no;
}
@property (nonatomic, strong) NSObject *obj;
@end
@implementation Student
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
Persion *son = [[Persion alloc] init];
son ->_height = 170;
NSLog(@"Persion 内存大小为 %zd 实际内存大小 %zd",class_getInstanceSize([Persion class]),malloc_size((__bridge const void *)(son)));
Student *stu = [[Student alloc] init];
stu -> _no = 5;
stu -> _height = 4;
stu.obj = [[NSObject alloc] init];
NSLog(@"Student 内存大小为 %zd 实际内存大小 %zd",class_getInstanceSize([Student class]),malloc_size((__bridge const void *)(stu)));
}
return 0;
}
打印出结果
2020-06-10 14:14:31.967377+0800 day_1[1263:3279976] Persion 内存大小为 16 实际内存大小 16
2020-06-10 14:14:31.967848+0800 day_1[1263:3279976] Student 内存大小为 24 实际内存大小 32
class_getInstanceSize 获取一个类生成的实力对象所需要的最小内存大小。
malloc_size 获取的是该对象实际分配的内存大小。
OC对象内存分配机制
通过代码不难看出 NSObject实际分配的内存带下是16个字节,但是在NSObject_IMPL结构体中仅仅只有isa指针变量,一个指针所占内存为8个字节。
通过阅读objc4的源代码
size_t instanceSize(size_t extraBytes) {
size_t size = alignedInstanceSize() + extraBytes;
// CF requires all objects be at least 16bytes.
if (size < 16) size = 16;
return size;
}
可以看出OC对象最小内存大小最小单位为16个字节。
上面Student对象为什么最小内存应该是24字节,但是分配了32个字节呢?
具体原因是Apple系统中的malloc函数分配内存空间时,内存是根据一个bucket的大小来分配的。bucket的大小是16,32,48,64,80 ...,可以看出系统是按16的倍数来分配对象的内存大小的。
由此可见,OC对象大小最小分配16个字节,且分配的内存空间大小为16的倍数。
实例对象 类对象 元类对象的区别
实例对象里面主要存储的 isa 和 其他的成员变量。
类对象里面主要存储了 isa, superclass ,属性,对象方法列表,协议列表等,成员变量
元类对象里面主要存储了isa, superclass, 类方法。
网友评论