返回

iOS底层-Runtime方法快速查找(下)

IOS

在 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 底层原理至关重要。

常见问题解答

  1. 什么是 selector?

    selector 是一个 SEL 类型的对象,它标识一个方法。它本质上是一个无符号整数,用于快速查找方法。

  2. 什么是 IMP?

    IMP 是一种指向方法实现的指针。它指定了在调用方法时要执行的代码。

  3. 为什么方法查找在 iOS Runtime 中如此重要?

    方法查找是 Runtime 的核心,因为它使消息发送、KVO 等特性得以实现。

  4. iOS Runtime 中的二分查找算法是如何工作的?

    iOS Runtime 使用了一个定制的二分查找算法,该算法利用 Method List 中方法按 selector 排序的事实。

  5. Category 中的方法查找与类中的方法查找有何不同?

    Category 没有继承链,因此它们的 IMP 查找过程在 Method List 中进行,而不用沿着继承链向上查找。