返回

iOS 底层:剖析类的本质(类对象结构和方法存放位置)

IOS

在上一篇文章中,我们深入浅出地介绍了 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 底层。