iOS底层-Runtime方法快速查找(下)
2023-09-04 07:36:09
在 iOS Runtime 中高效查找方法的深入解析
iOS Runtime 提供了一套强大的机制来查找方法,从而实现诸如消息发送、KVO 等功能。本文将深入探讨 iOS Runtime 中快速查找方法的流程,帮助你理解底层机制。
Method List 和 objc_method 结构
每个类都维护着一个 Method List,其中包含指向该类所有方法信息的指针。Method List 由以下结构定义:
typedef struct objc_method_list *MethodList;
struct objc_method_list {
unsigned int entsize; // sizeof(struct objc_method)
unsigned int count; // methods的个数
struct objc_method *methods; // 指向第一个method
};
Method List 中的每个条目都对应一个 objc_method 结构:
struct objc_method {
SEL _sel; // selector
char * _types; // 方法的类型签名
IMP _imp; // 方法的IMP
};
在 Method List 中查找方法
要查找一个方法,需要在 Method List 中进行二分查找。iOS Runtime 使用了一个高效的二分查找算法,该算法利用了以下事实:Method List 中的方法是按 selector 排序的。
Method *method = bsearch(&selector, method_list->methods, method_list->count, sizeof(Method), compare_methods);
沿着继承链查找方法
如果在当前类中找不到该方法,就需要沿着继承链向上查找父类。类结构中有一个指向父类的指针,允许我们访问父类的 Method List。
Class superclass = object_getClass(object);
MethodList superclass_method_list = class_getMethodList(superclass);
Category 中的方法查找
Category 没有继承链,但它们的 IMP 查找过程与类类似。Category 维护着自己的 Method List,可以在其中查找方法。
Category *category = object_getClass(object);
MethodList category_method_list = category_getMethodList(category);
示例代码
以下示例代码演示了如何使用 Runtime 在类中查找方法:
Class MyClass = objc_getClass("MyClass");
SEL mySelector = @selector(myMethod:);
Method method = class_getInstanceMethod(MyClass, mySelector);
IMP imp = method_getImplementation(method);
结论
iOS Runtime 使用高效的方法查找机制,使方法调用、消息发送和 KVO 等功能得以实现。了解该流程对于深入理解 iOS 底层原理至关重要。
常见问题解答
-
什么是 selector?
selector 是一个 SEL 类型的对象,它标识一个方法。它本质上是一个无符号整数,用于快速查找方法。
-
什么是 IMP?
IMP 是一种指向方法实现的指针。它指定了在调用方法时要执行的代码。
-
为什么方法查找在 iOS Runtime 中如此重要?
方法查找是 Runtime 的核心,因为它使消息发送、KVO 等特性得以实现。
-
iOS Runtime 中的二分查找算法是如何工作的?
iOS Runtime 使用了一个定制的二分查找算法,该算法利用 Method List 中方法按 selector 排序的事实。
-
Category 中的方法查找与类中的方法查找有何不同?
Category 没有继承链,因此它们的 IMP 查找过程在 Method List 中进行,而不用沿着继承链向上查找。