返回

iOS 底层揭秘:探究类的本质

IOS

在 iOS 开发中,类是编程的基础,它们定义了对象的结构和行为。然而,类的本质却鲜为人知,常常引发开发者的好奇和探索。本文将深入 iOS 底层,揭开类的神秘面纱,带你领略类在内存中的布局,对象与类的关联,以及类的内存管理机制。

类在内存中的布局

在 Objective-C 中,类在内存中以结构体的形式存在,称为 objc_class。这个结构体包含了类的元信息,包括类名、父类、实例变量、方法列表等。

struct objc_class {
    Class isa;
    Class superclass;
    const char *name;
    long version;
    long info;
    long instance_size;
    long ivar_layout_size;
    long weak_ivar_size;
    MethodList *methodLists;
    Class *protocols;
    const char **ivars;
    const char **weak_ivars;
    void *instance_variables;
};

对象与类的关联

每个对象都通过一个称为 isa 的指针与类关联。isa 指针指向对象的类结构体,提供了对象所属类的元信息。

@interface NSObject
{
    Class isa;
}
@end

类的内存管理

类在内存中是静态分配的,这意味着它们在程序运行期间始终驻留在内存中。当一个类被加载到内存时,它会被存储在名为 _objc_classrefs 的数据段中。这个数据段是一个全局变量,包含了所有已加载类的地址。

extern const void *_objc_classrefs;

当一个类不再需要时,它不会被释放,而是被标记为非活跃。这有助于减少内存开销,并避免由于频繁的类加载和卸载而导致的性能下降。

实锤类的唯一性

通过以上分析,我们可以验证类的唯一性。由于类在内存中以结构体的形式存在,并且是静态分配的,因此在任何给定的时刻,一个类只有一个实例。即使创建了多个该类的对象,它们仍然共享同一个类结构体。

Class CJPerson = objc_getClass("CJPerson");
Class CJPerson2 = objc_getClass("CJPerson");

// CJPerson 和 CJPerson2 指向相同的类结构体
assert(CJPerson == CJPerson2);

结论

通过深入探索 iOS 底层,我们揭开了类的本质。我们了解了类在内存中的布局,对象与类的关联,以及类的内存管理机制。这些知识对于理解 iOS 开发的底层原理至关重要,可以帮助开发者写出更高效、更健壮的代码。