面试题答案
一键面试元类(Meta Class)概念
在Objective-C中,元类是一种特殊的类对象,每个类都有一个对应的元类。元类存储类方法,而普通类存储实例方法。
在类方法存储与调用中的作用
- 存储:类方法存储在元类的方法列表中。例如,假设有一个类
MyClass
,其类方法+(void)classMethod
就存储在MyClass
对应的元类的方法列表里。 - 调用:当调用类方法时,消息会发送到类的元类上。因为元类存储类方法,runtime会在元类的方法列表中查找对应的方法实现。比如
[MyClass classMethod]
,runtime首先找到MyClass
的元类,然后在元类的方法列表中查找classMethod
的实现。
在对象的isa指针指向关系中的作用
- 实例对象:实例对象的
isa
指针指向其所属的类。例如,MyClass
的实例对象myObject
的isa
指向MyClass
。 - 类对象:类对象的
isa
指针指向它的元类。所以MyClass
的isa
指向MyClass
的元类。这使得类对象能找到存储类方法的地方。 - 元类对象:元类对象的
isa
指针指向根元类。根元类的isa
指针指向自身。这种链式关系构成了整个类体系的基础。
在运行时机制中的关键作用
- 动态方法解析:在运行时,如果类接收到无法识别的消息,runtime会首先在类的方法列表中查找,若找不到则会在元类的方法列表中查找(针对类方法)。这一过程依赖元类来实现类方法的动态解析。
- 消息转发:当动态方法解析无法找到方法实现时,会进入消息转发流程。元类在这一过程中参与类方法的转发,确保类方法的处理符合运行时机制。
基于runtime源码分析
在runtime源码中,objc_class
结构体定义了类的相关信息,其中isa
指针体现了上述的指向关系。元类的存在使得类方法的存储和调用得以合理实现。例如,在objc_msgSend
函数中,当处理类方法调用时,会通过类的isa
指针找到元类,进而查找方法实现。
实际应用案例
假设有一个工具类Utils
,其中有一个类方法+(NSString *)generateUUID
用于生成唯一标识符。在实际调用[Utils generateUUID]
时,runtime通过Utils
类的isa
指针找到其元类,然后在元类的方法列表中找到generateUUID
的实现并执行,这清晰展示了元类在类方法调用中的作用。同时,通过runtime提供的一些函数如class_getClassMethod
等,也能进一步验证元类对类方法的管理。