【iOS底层】09:objc_msgSend慢速查找

本文详细探讨了objc_msgSend方法在找不到对应imp时,如何执行__objc_msgSend_uncached并进行慢速查找的过程。从汇编到C++,分析了lookUpImpOrForward方法的实现,包括二分查找的细节。最后总结了慢速查找的递归查找流程,即当在当前类找不到imp时,会逐级向上查找父类直至找到或返回forward_imp。
摘要由CSDN通过智能技术生成

回顾:

上边博客分析了objc_msgSend通过receiver和SEL查找到对应imp的过程,这篇我们探索下如果最终未找到imp,执行的__objc_msgSend_uncached这个方法。

一、真机跟汇编流程 (可以真机调试的小伙伴自行探索)

register read x1

读各种内存比对,然后验证回顾并加深objc_msgSend流程。

二、__objc_msgSend_uncached

汇编就只有这么几行:

STATIC_ENTRY __objc_msgSend_uncached
	UNWIND __objc_msgSend_uncached, FrameWithNoSaves

	// THIS IS NOT A CALLABLE C FUNCTION
	// Out-of-band p15 is the class to search
	
	MethodTableLookup
	TailCallFunctionPointer x17  //br $0 返回执行$0

	END_ENTRY __objc_msgSend_uncached

 宏TailCallFunctionPointer

.macro TailCallFunctionPointer
	// $0 = function pointer value
	br	$0
.endmacro
.macro MethodTableLookup
	
	SAVE_REGS MSGSEND

	// lookUpImpOrForward(obj, sel, cls, LOOKUP_INITIALIZE | LOOKUP_RESOLVER)
	// receiver and selector already in x0 and x1
	mov	x2, x16
	mov	x3, #3
	bl	_lookUpImpOrForward

	// IMP in x0
	mov	x17, x0

	RESTORE_REGS MSGSEND

.endmacro

重点是_lookUpImpOrForward,但全局搜索不到,那么去掉下划线我们再全局搜索,最终在objc-runtime-new.mm文件中找到了该函数。

 我们终于又回到了C++的世界,不用再看晦涩的汇编了。

疑问:为什么objc_msgSend要用汇编来写呢?
答:

  1. 汇编接近机器语言,执行比较快,保持高效率。
  2. 安全。
  3. 更加动态化。

三、慢速查找流程

遍历寻找imp的过程是比较耗时&#x

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值