iOS Runtime中如何通过SEL找到IMP

本文详细阐述了在iOS Runtime中,如何通过SEL(选择子)找到IMP(实现)。从苹果开源的Runtime底层汇编代码开始,介绍了从方法缓存查找,到全局搜索,再到动态方法解析和消息转发的过程。在没有找到对应IMP时,系统会执行消息转发流程,最终确保消息的正确处理。同时,文章提到了通过特定途径查看方法调用堆栈信息,以便于调试和理解运行时机制。
摘要由CSDN通过智能技术生成

objc_msgSend(id self, SEL _cmd, ...) 中SEL找到IMP的流程

以下是苹果开源代码中Runtime底层的部分删减后的汇编代码

ENTRY _objc_msgSend
    ldr x13, [x0]       // x13 = isa
    and x16, x13, #ISA_MASK // x16 = class
    cmp x0, #0          // nil check and tagged pointer check
    b.le    LNilOrTagged        //  (MSB tagged pointer looks negative)
LGetIsaDone:
    CacheLookup NORMAL      // calls imp or objc_msgSend_uncached

LNilOrTagged:
    b.eq    LReturnZero     // nil check
    END_ENTRY _objc_msgSend

1.首先会进入汇编中 ENTRY _objc_msgSend

2.如果指针小于等于 LNilOrTagged 直接return返回

3.通过isa 找到相应类class

4.CacheLookup : NORMAL
CacheLookup源码中注释为:
Locate the implementation for a selector in a class method cache.
在类的方法缓存中 为 SEL 定位到 IMP

5.此时全局搜索CacheLookup,在objc_msg_arm64.s中会找到其对应的宏CacheHitCheckMissadd

.macro CacheLookup

1:  CacheHit $0         // call or return imp 
    返回IMP,并执行 
    <1> MESSENGER_END_FAST 结束快速查找路径
    <2> GETIMP 返回IMP
    <3> LOOKUP 

2:  CheckMiss $0            // miss if bucket->sel == 0 
    执行
    <1> GETIMP LGetImpMiss 没找到IMP
    <2> __objc_msgSend_uncached
    <3> __objc_msgLookup_uncached 

3:  add x12, x12, w11, UXTW #4  // x12 = buckets+(mask<<4)
    执行
    <1> CacheHit
    <2> CheckMiss
    <3> JumpMiss 

6.当执行__objc_msgSend_uncached时,说明没有相应缓存。将会在__objc_msgSend_uncached中执行MethodTableLookup

STATIC_ENTRY __objc_msgSend_uncached    
    MethodTableLookup
END_ENTRY __objc_msgSend_uncached

MethodTableLookup的宏定义中会发现__class_lookupMethodAndLoadCache3
全局搜索__class_lookupMethodAndLoadCache3发现没有什么多余的东西可以看,尝试去掉前边的_后发现新大陆!


汇编通过_class_lookupMethodAndLoadCache3方法跳转到了C,并且调用了lookUpImpOrForward<

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值