返回

iOS底层原理:探秘类的结构

IOS

iOS的世界中,万物皆对象,每个对象背后都有一个类。类的内部结构决定了对象的行为和特性。本文将深入探究类的结构,揭开它的神秘面纱。

元类探索

通过前面文章的学习,我们了解到每个类都有一个指向元类的isa指针。那么,元类本身的isa又指向什么呢?

为了解开这个谜团,让我们进行一个试验:

#import <Foundation/Foundation.h>

@interface MyClass : NSObject
@end

@implementation MyClass
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Class cls = [MyClass class];
        Class metaClass = object_getClass(cls);
        Class metaMetaClass = object_getClass(metaClass);
        NSLog(@"cls: %p, metaClass: %p, metaMetaClass: %p", cls, metaClass, metaMetaClass);
    }
    return 0;
}

运行代码,输出结果为:

cls: 0x10424b2b0, metaClass: 0x10400d690, metaMetaClass: 0x10400e100

可以看到,cls指向的对象地址(0x10424b2b0)与metaClass指向的对象地址(0x10400d690)不同,说明metaClass指向的是另一个对象。

那么,metaMetaClass又指向什么呢?NSLog输出结果显示,它指向的对象地址为0x10400e100。这正是NSObject的元类,也称为根元类(Root Meta-Class)。

由此可知,每个类的元类都指向其父类的元类,而根元类没有父元类,它的元类指向自身。

类结构分析

那么,类的内部结构是如何的呢?

类结构在内存中以两种形式存在:

  1. 元数据结构 :类本身的信息,包括类名、父类、实例变量、方法列表等。
  2. 方法实现 :实现类的方法代码。

元数据结构

类的元数据结构是一个objc_class结构体,包含以下主要成员:

  • name:类的名称。
  • superclass:类的父类。
  • isa:指向元类的指针。
  • instanceSize:类的实例大小(包括实例变量占用的空间)。
  • ivars:类实例变量列表。
  • methods:类方法列表。
  • protocols:类遵循的协议列表。

方法实现

类的每个方法都有一个对应的实现函数。方法实现的代码存储在称为方法实现区的特殊内存区域中。方法实现区由objc_method结构体表示,它包含以下主要成员:

  • sel:方法选择器(方法名和参数类型)。
  • imp:指向方法实现函数的指针。

小结

类的结构是iOS底层的重要组成部分。理解类的结构对于深入理解对象模型、内存管理和运行时机制至关重要。通过探索元类和分析类结构,我们可以揭开iOS底层世界的更多秘密。