9.消息慢速查找

338 阅读1分钟

一、汇编缓存找不到

CacheHit找不到会执行MissLabelDynamic image.png

CacheLookup NORMAL, _objc_msgSend, __objc_msgSend_uncached

.macro CacheLookup Mode, Function, MissLabelDynamic, MissLabelConstant

由上面2行代码可知,MissLabelConstant是传入的__objc_msgSend_uncached

image.png __objc_msgSend_uncached中执行MethodTableLookup,MethodTableLookup中执行_lookUpImpOrForward

总体流程:MissLabelDynamic->__objc_msgSend_uncached->MethodTableLookup->_lookUpImpOrForward(C++函数)

二、慢速查找流程

在objc-runtime-new.mm中lookUpImpOrForward函数 image.png image.png 1.6435行checkIsKnownClass函数,判断类是否注册过 image.png isKnownClass函数 image.png 2.6437行realizeAndInitializeIfNeeded_locked函数,一直点击找到realizeClassWithoutSwift函数,一直顺着继承链初始化,并递归查找 image.png 3.6451行CONFIG_USE_PREOPT_CACHES先在缓存中查找一次,防止ro rw methodlist初始化之后,在插入函数,做容错

4.6458行getMethodNoSuper_nolock函数 image.png 5.search_method_list_inline函数 image.png 6.findMethodInSortedMethodList函数(issmalllist是M1的电脑) image.png 7.findMethodInSortedMethodList函数(二分查找法)并且命中之后还有一个判断,这是因为category的方法会插入到列表的前面,也就是说调用的方法是category中的 image.png 8.6458行当找到函数之后 goto done 会执行log_and_fill_cache(把找到的函数缓存起来) image.png 9.6478行找不到会查找父类的 执行imp = cache_getImp(curClass, sel),而cache_getImp在汇编中,缓存中是没有的,也就是说流程是,先在缓存中查找,再去父类的methodlist中查找,找不到,再去父类的父类的methodlist中查找