OC笔记 - 对象的本质
前言
1 - iOS中的 OC代码,底层是由 C/C++编写的,OC面向对象也是基于 C/C++的数据结构实现的:OC --> C/C++ --> 汇编语言 --> 机器语言
NSObject对象本质
1 - NSObject对象是一个结构体,里面只有一个成员变量 isa
1 #import2 3 // 底层实现:其实是 C++结构体 4 struct NSObject_IMPL { 5 Class isa; 6 }; 7 8 int main(int argc, const char * argv[]) { 9 10 // 声明一个 NSObject对象 11 NSObject *obj = [[NSObject alloc] init]; 12 return 0; 13 14 }
解析图示:我们声明的指针变量 obj指向对象的地址其实就是 isa指针的地址,实际占 8个字节,但是系统默认分配 16个字节大小
OC对象本质
1 - 先看代码:在 main.m文件中声明并实现 Student
1 #import2 // 底层实现 3 struct Student_IMPL{ 4 5 // 实际上 Student对象转换成 C++结构体是这个样子 6 // struct NSObject_IMPL NSObject_IVARS;// 我们知道 NSObject_IMPL中其实就是一个 isa指针 7 // 所以可简化成 8 Class isa; 9 10 // 实例变量 11 int _no; 12 int _age; 13 14 }; 15 16 @interface Student : NSObject{ 17 @public 18 int _no; 19 int _age; 20 } 21 22 @end 23 24 @implementation Student 25 26 @end 27 28 int main(int argc, const char * argv[]) { 29 30 Student *stu = [[Student alloc] init]; 31 stu->_no = 4; 32 stu->_age = 5; 33 34 // 验证底层实现是否正确 35 // 把 stu对象强转成结构体:OC转换成 C/C++ 有时需要使用 __bridge关键字 36 struct Student_IMPL *stuImpl = (__bridge struct Student_IMPL *)stu; 37 NSLog(@"%d %d",stuImpl->_no,stuImpl->_age); // 4 5 38 39 return 0; 40 41 }
图示
2 - 有这么两个类,请问在 64位环境下一个 Person对象、Student对象各占多少内存空间
实际上 Person对象内存大小 = size( NSObject对象) + size(_age) = 8 + 4 =12;Student对象内存大小 = size( Person对象) + size(_no) = 12 + 4 = 16
但是有内存对齐的缘故,系统最终会给 NSObject对象分配 16个字节,多出 8个未使用的字节空间用来存储 _age,Person对象最终得到的分配空间是 16字节
同样 Student对象中的 Person对象(16 字节)还剩 16 - size(isa) - size(_age) = 4 字节,刚好用来存放 _no,所以 Student对象最终得到分配的空间也是 16字节
class_getInstanceSize | malloc_size
1 - class_getInstanceSize:计算对象实际内存大小;malloc_size 计算系统为对象分配的内存大小
#import#import #import int main(int argc, const char * argv[]) { NSObject *objc = [NSObject new]; NSLog(@"%zd",class_getInstanceSize([objc class])); // 8 NSLog(@"%zd",malloc_size(objc)); // 16 return 0; }