本篇文章主要介绍了" NSObject 底层本质",主要涉及到方面的内容,对于IOS开发感兴趣的同学可以参考一下:
一、OC 转 C/C++二、NSObject 对象内存布局三、NSObject 内存大小四、OC 对象内存布局五、OC 对象内存大小一、OC 转 C/C++OC...
size_t instanceSize(size_t extraBytes) {
size_t size = alignedInstanceSize() + extraBytes;
// CF requires all objects be at least 16 bytes.
if (size < 16) size = 16;
return size;
}
3.4 小结
综上,系统分配了 16 个字节给 NSObject 对象(通过 malloc_size 函数获得),但 NSObject 对象内部只使用了 8 个字节的空间,这8个字节主要用来存放 isa( 64bit 环境下,可以通过 class_getInstanceSize 函数获得)。
四、OC 对象内存布局
4.1 简单对象
@interface Student : NSObject
{
@public
int _no;
int _age;
}
@end
@implementation Student
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
Student *stu = [[Student alloc] init];
}
return 0;
}
利用 xcrun 命名生成 C/C++ 代码,代码中会包含如下部分:
struct Student_IMPL {
Class NSObject_IMP NSObject_IVARS;
int _no;
int _age;
};
其中NSObject_IMP 定义为:
struct NSObject_IMPL {
Class isa;
};
Student_IMP底层进而可转为如下结构,不难看出如果对象之间存在继承关系,最终子类转化对应的结构体会包含父类的结构体成分,且父类结构体成份在前。
struct Student_IMPL {
Class isa;
int _no;
int _age;
};
为了进一步说明OC对象底层是结构体实现的,可以将OC对象强制转为结构体,发现代码依然正常运行。
Student *stu = [[Student alloc] init];
stu->_no = 4;
stu->_age = 5;
//使用__bridge 将 OC 转为 C
struct Student_IMPL *stuImpl = (__bridge struct Student_IMPL *)stu;
NSLog(@"no is %d, age is %d", stuImpl->_no, stuImpl->_age);
结合上述代码,可以总结出Student对象的底层实现结构图:
