方法的本质之方法的慢速查找
2024-01-22 01:43:00
OC底层——方法的本质探究之方法的慢速查找
在上一篇文章中,我们分析了方法的本质是消息的发送,并主要探究了方法的快速查找流程,即去类的缓存中查找。如果缓存中没有查找到,就会JumpMiss,进入__objc_msgSend_uncached
流程。本文中,我们就来探究一下__objc_msgSend_uncached
,也就是方法的慢速查找流程。
方法的慢速查找流程
方法的慢速查找流程分为以下几个步骤:
-
类族查找 :首先,
__objc_msgSend_uncached
会通过类族查找(objc_lookUpClass方法)来查找实现该方法的类。类族查找的过程是:首先在当前类的类族中查找,如果找不到,就依次在父类的类族中查找,直到找到为止。如果在整个类族中都找不到,则返回nil
。 -
私有API调用 :如果在类族查找中找到了实现该方法的类,
__objc_msgSend_uncached
会调用私有API_objc_msgSend_uncached
(注意,此方法与__objc_msgSend_uncached
名称相同,但不是同一个方法)。_objc_msgSend_uncached
会通过方法列表查询流程(MethodTable)来查找实现该方法的方法。 -
方法列表查询 :方法列表查询流程是通过遍历类的方法列表来查找实现该方法的方法。方法列表是以消息选择器为键,以方法实现为值的哈希表。如果在方法列表中找到了实现该方法的方法,则返回该方法的实现。否则,继续遍历父类的
MethodTable
,直到找到为止。如果在整个MethodTable
中都找不到,则返回nil
。 -
执行方法 :如果在方法列表查询中找到了实现该方法的方法,
__objc_msgSend_uncached
会执行该方法。方法执行的过程是:首先将消息的参数压入栈中,然后调用该方法的实现。方法执行完成后,将返回值压入栈中。
慢速查找流程的优化
在慢速查找流程中,最耗时的步骤是类族查找和方法列表查询。为了优化慢速查找流程,可以采用以下几种方法:
-
使用缓存 :可以通过缓存类族查找和方法列表查询的结果来优化慢速查找流程。这样,当下次需要查找同一个方法时,就可以直接从缓存中获取结果,而无需重新进行查找。
-
使用快速查找 :如果知道要查找的方法的类,可以直接使用快速查找流程来查找该方法。快速查找流程要比慢速查找流程快得多。
-
使用私有API :可以使用私有API
_objc_msgSend_uncached
来直接调用方法列表查询流程。这样可以避免类族查找的开销。
慢速查找流程的总结
方法的慢速查找流程是通过类族查找、私有API调用和方法列表查询来查找实现该方法的方法。慢速查找流程要比快速查找流程慢得多,因此在实际开发中应该尽量避免使用慢速查找流程。