返回

编程进阶之Class的本质探索

IOS

Class:OC编程中的类与元类

在OC编程中,Class 是一个至关重要的概念,它同时代表着类对象元类对象 。它们在内存中都是指向objc_class 结构体的指针,本文将深入探讨Class的本质,揭示其内部结构和工作原理。

Class的底层结构

Class对象实际上是一个指向objc_class结构体的指针。objc_class结构体包含了关于类或元类的大量信息,如类名、父类、实例变量列表、方法列表等。

struct objc_class {
    Class isa;
    Class superclass;
    const char *name;
    long version;
    long info;
    long instance_size;
    struct objc_ivar_list *ivars;
    struct objc_method_list **methodLists;
    struct objc_cache *cache;
    struct objc_protocol_list *protocols;
};

Class的内存结构

Class对象在内存中以结构体的方式存储,它包含了多个字段,每个字段都有其特定的含义和作用。

  • isa指针: 指向该类的元类 ,元类也是一个Class对象,它管理着该类及其实例。
  • superclass指针: 指向该类的父类 ,父类也是一个Class对象,子类可以继承父类的属性和方法。
  • name: 该类的名称,是一个以'\0'结尾的C字符串。
  • version: 该类的版本号,用于标识该类的不同版本。
  • info: 该类的信息标志,用于标识该类的某些特性,如是否为抽象类等。
  • instance_size: 该类实例的大小,即实例变量在内存中占用的字节数。
  • ivars: 该类的实例变量列表,包含了该类实例变量的名称、类型和偏移量等信息。
  • methodLists: 该类的类方法和实例方法的列表,包含了这些方法的名称、类型、实现等信息。
  • cache: 该类的缓存,用于存储一些常用的信息,如类名、父类、实例变量列表等。
  • protocols: 该类遵循的协议列表,包含了这些协议的名称和版本号等信息。

Class的创建

Class对象可以通过objc_allocateClassPair() 函数创建,该函数接收两个参数:父类和类名。

Class objc_allocateClassPair(Class superclass, const char *name, long extraBytes);

其中,superclass 参数指定该类的父类,name 参数指定该类的名称,extraBytes 参数指定该类需要分配的额外内存空间。

创建的Class对象是一个未完成的类对象,它还需要通过objc_registerClassPair() 函数注册到运行时系统中。

void objc_registerClassPair(Class cls);

注册完成之后,该类对象就可以被使用。

Class的使用

Class对象可以用来创建该类的实例,也可以用来获取该类的元类。

id objc_alloc(Class cls);
Class objc_getMetaClass(Class cls);

其中,objc_alloc() 函数用于创建该类的实例,objc_getMetaClass() 函数用于获取该类的元类。

总结

Class对象是一个指向objc_class结构体的指针,它包含了关于类或元类的大量信息。Class对象可以通过objc_allocateClassPair()函数创建,并通过objc_registerClassPair()函数注册到运行时系统中。Class对象可以用来创建该类的实例,也可以用来获取该类的元类。

常见问题解答

  1. 什么是Class对象的isa指针?

    • Class对象的isa指针指向该类的元类,元类管理着该类及其实例。
  2. Class对象的instance_size有什么用?

    • Class对象的instance_size表示该类实例在内存中占用的字节数。
  3. Class对象如何创建?

    • Class对象可以通过objc_allocateClassPair()函数创建,该函数接收父类和类名作为参数。
  4. Class对象如何使用?

    • Class对象可以用来创建该类的实例,也可以用来获取该类的元类。
  5. 元类和类对象有什么区别?

    • 元类管理该类及其实例,而类对象表示该类的具体实现。