本文由快学吧个人写作,以任何形式转载请表明原文出处
一、材料预备
objc4-818.2
对应mac的版本是11.1。可根据自己的系统版本挑选可以进行调试的源码。
二、思路
- 为什么要看objc_msgSend?
调用办法的实质便是objc_msgSend
- objc_msgSend在哪里?
在runtime中
- objc_msgSend是什么写的?
汇编
- objc_msgSend为什么用汇编?
C言语是静态言语。不行能写一个函数用来保留不知道的参数,还要做到跳转任一函数的指针。
汇编是更挨近机器指令的言语,
objc_msgSend的功用就决定了它需要更快。
- 为什么要用objc4的源码?
由于objc_msgSend的源码是在
libobjc.A.dyld库中,objc4里有这个库。
三、创立代码
- 在818.2中创立一个类(我创立的是JDPerson),继承于NSObject。而且界说一个实例办法。然后在main.m中创立实例,并调用这个实例办法。并在调用实例办法这一行打断点。
- 翻开汇编
- 运行项目
四、有关汇编的简单根底
五、objc_msgSend的源码
1. 如何找到objc_msgSend的源码
在818.2的源码中查找objc_msgSend,找到arm64环境下的objc_msgSend,并在其间找到带ENTRY的objc_msgSend,由于ENTRY是进入的意思。
2. objc_msgSend汇编解析
1. ENTRY _objc_msgSend,对消息接收者(id self,sel _cmd)判别处理,tagged pointer判别处理。
2. GetClassFromIsa_p16关于isa指针的处理,获得class(类)。
文件内查找GetClassFromIsa_p16。找到源码后,对其间的#if SUPPORT_INDEXED_ISA不需要看它里面的内容,找__LP64__。
这里的ExtractISA还不知道是什么,大局查找ExtractISA :
这里的$1便是isa,$0= $1 & #ISA_MASK。也便是类信息。
3. 回到主线,CacheLookup查找缓存
(1). CacheLookup的注释 :
(2). 一些宏界说,CacheLookup源码中会用到的 :
(3). CacheLookup源码解析 :
(4). CacheHit射中缓存的源码 :
首要清晰一点,CacheLookup是NORMAL。
直接调用了一个TailCallCachedImp。
(5).
六、总结
- objc_msgSend会对消息的接收者进行判别处理。
- objc_msgSend中的
GetClassFromIsa_p16会对isa进行处理,获取其间的类信息。 - objc_msgSend会在
CacheLookup中经过类的内存平移获取到缓存,在缓存中拿到mask和buckets,经过掩码获取到单独的buckets。经过cache_hash获取sel的索引,经过遍历buckets中的bucket_t,查找缓存中是否有要调用的办法的完成。
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。




















