返回

objc_msgSend探索续一

IOS

从cache_t中读取方法

在上一篇cache_t探索文章中,我们探索了cache_t的作用,它是为了进行方法缓存,其目的是当方法再次调用时能更快的进行响应。接下来我们探究一下如何从cache_t中读取方法。

我们可以在源码中objc_msgSend的实现中找到相关代码:

static inline id objc_msgSend_uncached(id self, SEL op, ...)
{
    va_list ap;
    va_start(ap, op);
    id result = objc_msgSendSuper_uncached(self->class, self, op, ap);
    va_end(ap);
    return result;
}

id objc_msgSend(id self, SEL op, ...)
{
    if (self) {
        struct objc_method *cached_method = (struct objc_method *)
            get_method_in_cache(self->class, op);
        if (cached_method) {
            va_list ap;
            va_start(ap, op);
            id result = (*cached_method->imp)(self, self->class, op, ap);
            va_end(ap);
            return result;
        }
    }
    return objc_msgSend_uncached(self, op);
}

从代码中可以看出,objc_msgSend首先会检查self是否存在,如果存在,它会尝试从self的类中获取方法的缓存。如果找到了缓存的方法,它会使用该方法来调用,否则它会调用objc_msgSend_uncached来调用该方法。

objc_msgSend_uncached是一个没有缓存的方法调用函数。它直接调用objc_msgSendSuper_uncached来调用父类的方法。

Method Caching的实现原理

Method Caching的实现原理是将方法的调用信息存储在一个缓存中,当方法再次调用时,可以直接从缓存中读取,从而避免了反复查找和解析方法的过程,提高了方法调用的速度。

Method Caching的缓存机制是在运行时实现的。当一个方法第一次被调用时,系统会将该方法的调用信息存储在一个缓存中。这个缓存通常是一个哈希表,其中键是方法的selector,值是方法的调用信息。

当该方法再次被调用时,系统会先检查缓存中是否有该方法的调用信息。如果有,则直接从缓存中读取,否则,系统会重新查找和解析该方法,并将该方法的调用信息存储在缓存中。

Method Caching的应用场景

Method Caching可以用于各种场景,其中最常见的是:

  • 提高方法调用的速度。 Method Caching可以减少方法查找和解析的开销,从而提高方法调用的速度。这对于经常被调用的方法尤其重要。
  • 减少内存占用。 Method Caching可以减少方法的重复存储,从而减少内存占用。这对于内存有限的设备尤其重要。
  • 提高代码的可维护性。 Method Caching可以使代码更易于维护。当需要修改一个方法时,只需要修改缓存中的调用信息,而不需要修改所有的调用该方法的代码。

总结

objc_msgSend是Objective-C中最重要的函数之一。它负责调用方法。Method Caching是objc_msgSend的一个重要优化技术。它可以提高方法调用的速度,减少内存占用,并提高代码的可维护性。