方法的快速查找,OC底层之—方法的本质
2023-09-14 04:58:31
最近工作有点忙,博客和底层之路有点拉下了。之前不怎么写博客,拾起博客的时候虽然每次写的时候很花时间,但是写完的感觉还是很棒。探究的时候可能会枯燥,甚至抓狂,写出来的时候总觉得一切都值得了。也算是鼓励自己坚持下去。
上篇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为空,则直接返回NULL。
if (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程序的性能。