1-10.【OC】【基础】解释 实例对象 / 类对象 / 元类对象 的关系

2 阅读2分钟

在 Objective-C 中,实例、类、元类之间的关系被称为 “isa 指针走线图” 。这套设计是 Objective-C 能够实现“万物皆对象”和“运行时动态查找方法”的核心。

它们三者的关系可以用身份(是什么) 、**职责(存什么)指向(找谁)**来拆解:


1. 核心定义与角色

对象类型它是谁?存什么?(职责)
实例对象 (Instance)类生成的具体个体。成员变量的具体
类对象 (Class)描述实例的模板。实例方法列表、属性定义、协议。
元类对象 (Meta Class)描述类的类类方法列表(以 + 开头的方法)。

2. 三者的递进关系(isa 走线)

为了找到要执行的代码,Runtime 遵循一套严格的查找路径。你可以把 isa 想象成“向上级请示”的线:

  1. 实例对象isa 指向 类对象

    当你调用 [obj hello](实例方法)时,通过实例的 isa 去类对象里找。

  2. 类对象isa 指向 元类对象

    当你调用 [User alloc](类方法)时,通过类对象的 isa 去元类对象里找。

  3. 元类对象isa 指向 根元类 (Root Meta Class)

    通常是 NSObject 的元类。

  4. 根元类isa 指向 它自己

    这是查找链的终点。


3. 继承关系(Superclass 走线)

除了 isa 指向,它们还通过 superclass 指针维持着继承体系:

  • 类对象的 superclass 指向父类的类对象。
  • 元类对象的 superclass 指向父类的元类对象。
  • 特殊的闭环: 根元类(Root Meta Class)的 superclass 指向 根类(Root Class,即 NSObject)

这意味着一个有趣的现象: 如果你给 NSObject 写了一个实例方法(-),但你却对某个类调用了同名的类方法(+),如果元类里找不到,它最终会沿着继承链找到 NSObject 的实例方法并执行。


4. 为什么要搞得这么复杂?(引入元类的意义)

Objective-C 追求逻辑的一致性

  • 在 Smalltalk 的哲学里,“消息发送”必须有一个接收者。
  • 如果你想调用类方法 [User alloc],那么 User 这个“类”本身也必须是一个对象。
  • 既然类是对象,它就必须是某个更高级的类的实例。这个“更高级的类”就是元类

通过引入元类,Objective-C 成功地把实例方法类方法统一成了同一种处理机制:都是去该对象的 isa 指向的地方找方法列表。


总结

  • 实例存数据。
  • 存实例方法。
  • 元类存类方法。