OC笔记 - 对象的本质
作者:互联网
前言
1 - iOS中的 OC代码,底层是由 C/C++编写的,OC面向对象也是基于 C/C++的数据结构实现的:OC --> C/C++ --> 汇编语言 --> 机器语言
NSObject对象本质
1 - NSObject对象是一个结构体,里面只有一个成员变量 isa
1 #import <Foundation/Foundation.h> 2 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个字节
3 - 一个 NSObject对象占多少内存空间 ?NSObject对象里就有一个 isa指针,所占空间是一个指针大小(64位下 8字节;32位下 4字节)
OC对象本质
1 - 先看代码:我们在 main.m文件中声明并实现 Student
1 #import <Foundation/Foundation.h> 2 // 底层实现 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(isa) + size(_age) = 12;Student对象内存大小 = size(Person) + size(_no) = 12 + 4 = 16
因为内存对齐的缘故,最终 Person对象内存大小 = 16;Student对象内存大小 = 16
我们可以使用运行时函数 class_getInstanceSize计算内存大小,注意引用头文件
#import <objc/runtime.h>
NSLog(@"%zd",class_getInstanceSize([NSObject class]));
标签:int,OC,本质,对象,笔记,Student,NSObject,isa,IMPL 来源: https://www.cnblogs.com/self-epoch/p/16313030.html