其他分享
首页 > 其他分享> > OC笔记 - 对象的本质

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