返回
从类的结构分析理解isa指针的指向(上)
IOS
2023-09-18 17:59:53
前言
在Objective-C中,每个对象都有一个isa指针,这个指针指向该对象的类。isa指针是一个非常重要的概念,它可以帮助我们理解Objective-C中对象的内存布局,以及OOP的一些基本概念。
类的结构
在Objective-C中,类是一个数据结构,它包含了该类的一些信息,比如:
- 类名
- 父类
- 实例变量
- 方法
类在内存中是以一种特定的方式组织的,这种组织方式称为类的内存布局。类的内存布局如下图所示:
类结构:
+-------------------------------------+
| 实例变量区 |
+-------------------------------------+
| 方法区 |
+-------------------------------------+
| 类变量区 |
+-------------------------------------+
| 元类指针 |
+-------------------------------------+
| 父类指针 |
+-------------------------------------+
| 类名 |
+-------------------------------------+
其中:
- 实例变量区:存储该类的实例变量。
- 方法区:存储该类的方法。
- 类变量区:存储该类的类变量。
- 元类指针:指向该类的元类。
- 父类指针:指向该类的父类。
- 类名:该类的名称。
isa指针
isa指针指向该对象的类。在内存中,isa指针位于对象的实例变量区的最前面。如下图所示:
对象内存布局:
+-------------------------------------+
| isa指针 |
+-------------------------------------+
| 实例变量区 |
+-------------------------------------+
isa指针的指向
我们有一个对象LGPerson,继承与NSObject。我们来打印一下它的isa指针:
#import <objc/runtime.h>
int main() {
LGPerson *person = [[LGPerson alloc] init];
NSLog(@"%@", [NSString stringWithFormat:@"%p", object_getClass(person)]);
return 0;
}
输出结果:
0x100008c98
从输出结果可以看出,isa指针指向的是该对象的类。在本文中,isa指针指向的是LGPerson类。
我们可以继续追溯isa指针的指向,直到根元类。根元类是所有类的父类,它的isa指针指向它自己。如下图所示:
isa指针的指向:
+-------------------------------------+
| isa指针 |
+-------------------------------------+
| 类 |
+-------------------------------------+
| ... |
+-------------------------------------+
| 元类 |
+-------------------------------------+
| ... |
+-------------------------------------+
| 根元类 |
+-------------------------------------+
| isa指针 |
+-------------------------------------+
| 根元类 |
+-------------------------------------+
通过上面的分析,我们可以得出以下结论:
- isa指针指向该对象的类。
- isa指针可以帮助我们追溯对象的类继承关系。
- 根元类的isa指针指向它自己。
isa指针的疑问
在上面的分析中,我们提到isa指针指向该对象的类。但是,我们是如何知道isa指针指向的是哪个类的呢?
其实,isa指针指向的类是通过编译器生成的。编译器会在每个类的开头生成一个指向该类的指针,这个指针就是isa指针。如下图所示:
类结构:
+-------------------------------------+
| 实例变量区 |
+-------------------------------------+
| 方法区 |
+-------------------------------------+
| 类变量区 |
+-------------------------------------+
| 元类指针 |
+-------------------------------------+
| 父类指针 |
+-------------------------------------+
| 类名 |
+-------------------------------------+
| isa指针 |
+-------------------------------------+
编译器会在LGPerson类的开头生成一个指向LGPerson类的指针,这个指针就是LGPerson对象的isa指针。
结语
本文从类的结构分析的角度,来理解isa指针的指向。我们了解了isa指针的指向,以及如何通过isa指针追溯对象的类继承关系。我们还了解了isa指针是如何生成的。
在下一篇文章中,我们将继续分析isa指针,并了解isa指针在Objective-C中的其他应用。