缓存——方法缓存(下)
2023-10-16 07:38:27
iOS底层08——缓存——方法缓存(下)
objc_msgsend在objc-runtime.h中被声明为:
id objc_msgsend(id self, SEL op, ...) __attribute__((__nothrow__));
它的实现可以在objc-runtime-new.mm中找到:
id objc_msgsend(id self, SEL op, ...) {
va_list args;
va_start(args, op);
id result = _objc_msgSend_v(self, op, args);
va_end(args);
return result;
}
从中可以看出,objc_msgsend实际上是调用了_objc_msgSend_v,它接收一个id类型的self参数,一个SEL类型的op参数,以及一个不定长的参数列表。
_objc_msgSend_v的实现可以在objc-runtime-new.mm中找到:
id _objc_msgSend_v(id self, SEL op, va_list args) {
struct objc_super super = { self, self->class_pointer };
return _objc_msgSend_super(&super, op, args);
}
从代码中可以看出,_objc_msgSend_v实际上是调用了_objc_msgSend_super,它接收一个struct objc_super类型的super参数,一个SEL类型的op参数,以及一个不定长的参数列表。
_objc_msgSend_super的实现可以在objc-runtime-new.mm中找到:
id _objc_msgSend_super(struct objc_super *super, SEL op, va_list args) {
struct objc_cache *cache;
struct objc_method *imp;
cache = _objc_msgSend_uncached(super, op, &imp);
if (cache) {
return (*cache->imp)(super->receiver, super->class, imp, args);
}
return _objc_msgSend_uncached(super, op, &imp);
}
从代码中可以看出,_objc_msgSend_super首先调用_objc_msgSend_uncached来获取方法缓存和方法实现,如果方法缓存存在,则直接调用方法缓存中的方法实现来执行方法调用,否则调用_objc_msgSend_uncached来执行方法调用。
_objc_msgSend_uncached的实现可以在objc-runtime-new.mm中找到:
struct objc_cache * _objc_msgSend_uncached(struct objc_super *super, SEL op, struct objc_method **out_imp) {
struct objc_cache *cache;
struct objc_method *imp = _objc_lookupMethod(super->class, op);
if (imp) {
cache = _objc_cache_get(imp);
if (out_imp) {
*out_imp = imp;
}
return cache;
}
return NULL;
}
从代码中可以看出,_objc_msgSend_uncached首先调用_objc_lookupMethod来查找方法实现,如果方法实现存在,则调用_objc_cache_get来获取方法缓存,如果方法缓存存在,则返回方法缓存,否则返回NULL。
通过分析汇编层的代码,我们可以看到objc_msgsend是如何调用Cache相关函数来实现方法缓存的。这些函数通过查找方法实现、获取方法缓存、调用方法缓存中的方法实现等步骤来实现方法调用的优化,提高了程序的执行效率。