iOS 底层:剖析类的本质(类对象结构和方法存放位置)
2023-12-09 03:24:00
在上一篇文章中,我们深入浅出地介绍了 iOS 底层的对象本质,了解了 isa 指向的是类对象。那么,类(Class)的本质究竟是什么?在这篇文章中,我们将深入探究类的继承链、类对象的结构,并尝试获取方法和属性的存放位置。
一、类的继承链
类之间存在着继承关系,子类可以继承父类的属性和方法。在 Objective-C 中,类的继承链可以通过 isa 指针来追溯。isa 指针指向该类的父类,而父类的 isa 指针指向其父类,以此类推,最终指向根类 NSObject。
我们可以通过以下代码来查看类的继承链:
Class cls = [NSString class];
while (cls) {
NSLog(@"Class name: %@", cls);
cls = [cls superclass];
}
运行这段代码,我们可以看到 NSString 类的继承链如下:
NSString
NSObject
二、类对象的结构
类对象是类的元数据的对象。它包含了类的名称、父类、属性、方法等信息。我们可以通过以下代码来获取类的类对象:
Class cls = [NSString class];
objc_class* metaClass = object_getClass(cls);
类对象是一个 C 结构体,它包含了以下成员:
struct objc_class {
Class isa;
Class superclass;
const char *name;
long version;
long info;
long instance_size;
struct objc_method_list *methods;
struct objc_ivar_list *ivars;
struct objc_property_list *properties;
};
三、方法的存放位置
方法是类的成员函数,它定义了类的行为。方法被存储在类对象的 methods 成员变量中。methods 成员变量是一个指针,指向一个方法列表。每个方法列表项包含了方法的名称、实现函数的指针和方法的类型。
我们可以通过以下代码来获取类的方法列表:
Class cls = [NSString class];
objc_class* metaClass = object_getClass(cls);
struct objc_method_list *methods = metaClass->methods;
for (int i = 0; i < methods->method_count; i++) {
SEL selector = methods->method_list[i].method_name;
const char *name = sel_getName(selector);
NSLog(@"Method name: %s", name);
}
运行这段代码,我们可以看到 NSString 类的所有方法。
四、属性的存放位置
属性是类的成员变量,它定义了类的状态。属性被存储在类对象的 ivars 成员变量中。ivars 成员变量是一个指针,指向一个属性列表。每个属性列表项包含了属性的名称、类型和偏移量。
我们可以通过以下代码来获取类的属性列表:
Class cls = [NSString class];
objc_class* metaClass = object_getClass(cls);
struct objc_ivar_list *ivars = metaClass->ivars;
for (int i = 0; i < ivars->ivar_count; i++) {
const char *name = ivars->ivar_list[i].ivar_name;
NSLog(@"Property name: %s", name);
}
运行这段代码,我们可以看到 NSString 类的所有属性。
五、结语
在这篇文章中,我们探讨了 iOS 底层中类的本质,包括类对象的结构、方法存放位置、isa 指向、继承链和属性存放位置。希望这篇文章能帮助大家更好地理解 iOS 底层。