返回
深入探究isa和类结构:揭秘Objective-C语言幕后运行机制
IOS
2023-11-13 21:11:35
一、isa到元类
1. isa指针
isa指针是Objective-C语言中的一个关键概念,它指向对象的类对象。类对象是类信息的特殊对象,它包含了该类的方法列表、成员变量列表以及其他元数据。
2. isa指针的获取
对象的isa指针可以通过多种方式获取:
- 使用
class
。class
关键字返回对象的类对象。 - 使用
isa
指针。isa
指针直接指向对象的类对象。 - 使用
objc_getClass()
函数。objc_getClass()
函数接收一个类名作为参数,并返回该类的类对象。
3. isa指针的作用
isa指针的作用主要包括以下几个方面:
- 确定对象的类。通过isa指针,可以确定对象的类,从而调用该类的方法和访问该类的成员变量。
- 查找类的方法。当调用对象的方法时,编译器会根据isa指针找到该方法的实现。
- 确定对象的类型。isa指针可以用来确定对象的类型,从而进行类型检查。
二、isa走位图和继承链
1. isa走位图
isa走位图是isa指针中的一个重要组成部分。isa走位图包含了该对象继承链上的所有类。
2. isa走位图的结构
isa走位图的结构如下:
|--------------------|--------------------|
| Class | Class |
|--------------------|--------------------|
| Class | Class |
|--------------------|--------------------|
|...... |...... |
|--------------------|--------------------|
3. isa走位图的作用
isa走位图的作用主要包括以下几个方面:
- 快速查找继承链上的类。通过isa走位图,可以快速找到继承链上的所有类。
- 确定对象的类型。isa走位图可以用来确定对象的类型,从而进行类型检查。
三、源码分析类的结构
1. 类结构
Objective-C中的类结构如下:
struct objc_class {
Class isa; // 指向该类的元类
Class superclass; // 指向该类的父类
const char *name; // 该类的名字
long version; // 该类的版本号
long info; // 该类的信息
long instance_size; // 该类的实例大小
long ivar_layout; // 该类的成员变量布局
long method_count; // 该类的方法数量
struct objc_method_list **methodLists; // 该类的所有方法列表
struct objc_cache *cache; // 该类的缓存
struct objc_protocol_list *protocols; // 该类实现的所有协议
};
2. 类结构的组成部分
isa
指针:指向该类的元类。superclass
指针:指向该类的父类。name
:该类的名字。version
:该类的版本号。info
:该类的信息。instance_size
:该类的实例大小。ivar_layout
:该类的成员变量布局。method_count
:该类的方法数量。methodLists
:该类的所有方法列表。cache
:该类的缓存。protocols
:该类实现的所有协议。
四、指针和内存平移
1. 指针平移
指针平移是指将一个指针从一个内存地址移动到另一个内存地址。指针平移可以通过以下方式实现:
- 使用指针算术。指针算术可以通过
+
和-
运算符来实现。 - 使用
memmove()
函数。memmove()
函数可以将一个内存块从一个地址移动到另一个地址。
2. 内存平移的作用
内存平移的作用主要包括以下几个方面:
- 将对象从一个内存地址移动到另一个内存地址。
- 将数据从一个内存地址移动到另一个内存地址。
五、类的结构内存计算
1. 类的结构内存计算公式
类的结构内存计算公式如下:
sizeof(struct objc_class) = sizeof(Class) + sizeof(Class) + sizeof(const char *) + sizeof(long) + sizeof(long) + sizeof(long) + sizeof(long) + sizeof(struct objc_method_list **) + sizeof(struct objc_cache *) + sizeof(struct objc_protocol_list *)
2. 类的结构内存计算示例
假设一个类的结构如下:
struct objc_class {
Class isa; // 8字节
Class superclass; // 8字节
const char *name; // 8字节
long version; // 8字节
long info; // 8字节
long instance_size; // 8字节
long ivar_layout; // 8字节
long method_count; // 8字节
struct objc_method_list **methodLists; // 8字节
struct objc_cache *cache; // 8字节
struct objc_protocol_list *protocols; // 8字节
};
那么,该类的结构内存大小为:
sizeof(struct objc_class) = 8 + 8 + 8 + 8 + 8 + 8 + 8 + 8 + 8 + 8 + 8 = 88字节
六、lldb分析类的结构和类的bits数据分析
1. lldb分析类的结构
可以使用lldb来分析类的结构。以下命令可以分析类的结构:
po [class_name class]
2. lldb分析类的bits数据
可以使用lldb来分析类的bits数据。以下命令可以分析类的bits数据:
po [class_name class]->bits
3. lldb分析类的结构和类的bits数据示例
以下是在Objective-C中定义的一个类:
@interface MyClass : NSObject
@end
@implementation MyClass
- (void)sayHello {
NSLog(@"Hello, world!");
}
@end
可以使用lldb来分析该类的结构:
(lldb) po [MyClass class]
<objc_class: MyClass>
可以使用lldb来分析该类的bits数据:
(lldb) po [MyClass class]->bits
{isa = 0x0000000104d70b80, superclass = 0x0000000104d87db0, name = MyClass, version = 45, info = 0, instance_size = 32, ivar_layout = 0, method_count = 1, methodLists = 0x000000010c1e9310, cache = 0x00000000, protocols = 0x00000000}
从以上分析结果可以看出,MyClass
类的结构和bits数据与前面介绍的内容是一致的。