揭秘iOS isa——深入剖析类、对象、isa之间的底层结构
2023-11-09 00:57:51
前言
在上一篇文章中,我们对对象的底层本质和isa的原理进行了分析,发现对象里的isa成员变量很特别。在本文中,我们将从isa入手,继续探索类、对象和isa之间的底层结构。
首先,我们来看两个类,分别是XJPerson(继承自NSObject)和XJStudent(继承自XJPerson)。这两个类在内存中的布局如下图所示:
XJPerson:
+-------+ +-------+ +-------+
| isa | -> | isa | -> | isa |
+-------+ +-------+ +-------+
| name | | name | | name |
+-------+ +-------+ +-------+
| age | | age | | age |
+-------+ +-------+ +-------+
| gender | | gender | | gender |
+-------+ +-------+ +-------+
XJStudent:
+-------+ +-------+ +-------+
| isa | -> | isa | -> | isa |
+-------+ +-------+ +-------+
| name | | name | | name |
+-------+ +-------+ +-------+
| age | | age | | age |
+-------+ +-------+ +-------+
| gender | | gender | | gender |
+-------+ +-------+ +-------+
| score | | score | | score |
+-------+ +-------+ +-------+
从上图可以看出,XJPerson和XJStudent对象在内存中的布局是一致的,都包含了isa、name、age和gender这四个成员变量。其中,isa成员变量指向了该对象的类对象(XJPerson或XJStudent),而其他成员变量则存储了该对象特有的数据。
isa指针
isa指针是对象的一个成员变量,它指向了该对象的类对象。类对象也是一个对象,它存储了该类相关的信息,比如类名、成员变量列表、方法列表等。
isa指针在Objective-C和Swift中都有着重要的作用。在Objective-C中,isa指针用于确定对象的类型,并根据对象的类型调用相应的方法。在Swift中,isa指针用于确定对象的类型,并根据对象的类型进行类型检查。
类、对象和isa之间的关系
类、对象和isa之间的关系可以用以下三点来概括:
- 类是对象的模板,对象是类的实例。
- isa指针指向对象的类对象。
- 类对象存储了该类相关的信息,比如类名、成员变量列表、方法列表等。
这三点关系构成了类、对象和isa之间的基本结构。
内存布局
类、对象和isa在内存中的布局如下图所示:
+-------+ +-------+ +-------+
| isa | -> | isa | -> | isa |
+-------+ +-------+ +-------+
| name | | name | | name |
+-------+ +-------+ +-------+
| age | | age | | age |
+-------+ +-------+ +-------+
| gender | | gender | | gender |
+-------+ +-------+ +-------+
XJPerson:
+-------+ +-------+ +-------+
| isa | -> | isa | -> | isa |
+-------+ +-------+ +-------+
| name | | name | | name |
+-------+ +-------+ +-------+
| age | | age | | age |
+-------+ +-------+ +-------+
| gender | | gender | | gender |
+-------+ +-------+ +-------+
| score | | score | | score |
+-------+ +-------+ +-------+
XJStudent:
从上图可以看出,XJPerson和XJStudent对象在内存中的布局是一致的,都包含了isa、name、age和gender这四个成员变量。其中,isa成员变量指向了该对象的类对象(XJPerson或XJStudent),而其他成员变量则存储了该对象特有的数据。
运行时机制
运行时机制是iOS中非常重要的一个机制,它允许程序在运行时动态地加载、链接和执行代码。运行时机制的实现依赖于isa指针。
当程序运行时,系统会根据对象的isa指针找到该对象的类对象,然后根据类对象中的信息来确定对象的类型,并调用相应的方法。
运行时机制的应用非常广泛,比如动态加载库、动态类型检查、反射等。
示例
下面我们通过一个示例来说明isa指针的作用。
我们创建一个XJPerson对象和一个XJStudent对象,然后调用这两个对象的name属性。
XJPerson *person = [[XJPerson alloc] init];
person.name = @"张三";
XJStudent *student = [[XJStudent alloc] init];
student.name = @"李四";
NSLog(@"person.name = %@", person.name);
NSLog(@"student.name = %@", student.name);
输出结果为:
person.name = 张三
student.name = 李四
从输出结果可以看出,person.name和student.name的值分别为“张三”和“李四”。这是因为person对象和student对象的isa指针指向了不同的类对象,从而导致了不同的方法调用。
结语
本文深入探讨了iOS中的isa指针,剖析了类、对象和isa之间的底层结构,揭示了内存布局和运行时机制,并提供了清晰的示例和代码片段,帮助读者理解Objective-C和Swift中的内存管理和运行时机制。