返回

方法的快速查找,OC底层之—方法的本质

IOS

最近工作有点忙,博客和底层之路有点拉下了。之前不怎么写博客,拾起博客的时候虽然每次写的时候很花时间,但是写完的感觉还是很棒。探究的时候可能会枯燥,甚至抓狂,写出来的时候总觉得一切都值得了。也算是鼓励自己坚持下去。

上篇cache_t的结构和写入已经分析了,本篇就看下cache是如何快速找到方法的,cache的结构我们在上篇分析过了,现在就看看cache的实际使用场景是如何的。

最核心的一个方法就是getMethodImplementation()。定义如下:

Method  getMethodImplementation(Method m)

该方法的作用是:给定一个Method对象,返回该Method对应的实现。Method对象可以由class_getInstanceMethod()或class_getClassMethod()获取。

/**
 *  return NULL if method is not found
 */
MethodImpl getMethodImplementation(Method m)
{
    // 如果sel/name为空,则直接返回NULLif (m->sel == NULL || m->name == NULL) return NULL;

    /**
     *  该处 cache 分别是 class cache 和 metaclass cache,
     *  在该函数中 cache 由 [obj class] 决定,
     *  由于在查找 method 之前已经把当前类和其父类添加到 cache 中,
     *  故而在该函数中 m->sel 能够通过当前 cache 直接找到对应的 IMP。
     */
    MethodImpl imp = cache_getImplementation(m);
    if (imp != NULL) return imp;

    /**
     *  循环向上寻找 obj 对应的类,
     *  直到该类为 root class 或 method 已经找到。
     */
    Class cls = objc_getClass(object_getClass((id)obj));
    while (cls) {
        imp = cache_getImplementation(m);
        if (imp != NULL) return imp;
        cls = objc_getClass(cls);
    }

    return NULL;
}

从上面的方法中我们可以看出,getMethodImplementation()方法首先会尝试从cache中查找实现。如果在cache中找不到,则会循环向上寻找obj对应的类,直到该类为rootclass或method已经找到。

循环向上寻找类的过程如下:

Class cls = objc_getClass(object_getClass((id)obj));
while (cls) {
    imp = cache_getImplementation(m);
    if (imp != NULL) return imp;
    cls = objc_getClass(cls);
}

objc_getClass()方法的作用是:给定一个类名,返回该类的Class对象。object_getClass()方法的作用是:给定一个对象,返回该对象的类。

在循环向上寻找类的过程中,如果在cache中找到了实现,则直接返回该实现。如果在cache中没有找到实现,则继续向上寻找类。

直到找到rootclass或method为止。rootclass是指NSObject类。NSObject类是所有Objective-C类的基类。

getMethodImplementation()方法的实现非常简单,但是它却是一个非常重要的方法。因为它提供了快速查找方法的途径。

在Objective-C中,方法调用非常频繁。每当我们调用一个方法时,都会使用getMethodImplementation()方法来查找该方法的实现。

getMethodImplementation()方法的效率直接影响着Objective-C程序的性能。因此,Apple公司在设计getMethodImplementation()方法时,采用了非常巧妙的算法。

getMethodImplementation()方法首先会尝试从cache中查找实现。如果在cache中找到了实现,则直接返回该实现。

只有在cache中没有找到实现时,才会循环向上寻找类。这种算法可以大大提高getMethodImplementation()方法的效率。

因为cache是一个非常小的数据结构,而向上寻找类是一个非常耗时的操作。

通过使用这种算法,getMethodImplementation()方法可以快速地找到方法的实现,从而提高Objective-C程序的性能。