返回
iOS八股文(七)之objc_msgSend的动态解析和消息转发
IOS
2023-12-11 09:38:54
在上一篇文章中,我们了解了objc_msgSend过程中消息查找的流程,其中有个查找方法的函数名叫lookUpImpOrForward,字面翻译为“查找方法或者转发”。那么本文就来记录下objc_msgSend的动态解析和消息转发。
动态解析
动态解析发生在类加载时,且只发生一次。动态解析过程如下:
- 消息发送时,首先判断方法是否已经解析过,即查看
IMP
指针是否为NULL
,如果是,则执行动态解析。 - 动态解析时,会遍历当前类以及它的父类的
Method List
,寻找方法选择器对应的IMP
指针,如果找到,则将IMP
指针赋值给方法并返回。 - 如果在当前类以及其父类都没有找到对应的
IMP
指针,则会尝试调用resolver
方法进行动态解析。 - 如果
resolver
方法返回YES
,则会将解析后的IMP
指针赋值给方法并返回。 - 如果
resolver
方法返回NO
,则动态解析失败,objc_msgSend返回NULL
。
消息转发
消息转发发生在objc_msgSend动态解析失败时,消息转发流程如下:
- 当动态解析失败时,objc_msgSend会调用
forwardingTargetForSelector
方法,让对象有机会将消息转发给其他对象。 - 如果
forwardingTargetForSelector
方法返回nil
,则objc_msgSend调用methodSignatureForSelector
方法获取方法签名。 - 如果
methodSignatureForSelector
方法返回nil
,则消息转发失败,objc_msgSend返回NULL
。 - 如果
methodSignatureForSelector
方法返回非nil
,则objc_msgSend调用forwardInvocation:
方法,将消息转发给其他对象。 - 如果
forwardInvocation:
方法执行成功,则消息转发成功,objc_msgSend返回YES
。 - 如果
forwardInvocation:
方法执行失败,则消息转发失败,objc_msgSend返回NULL
。
在iOS开发中,objc_msgSend函数扮演着至关重要的角色。它负责消息的发送和方法的调用,并提供了动态解析和消息转发等机制来处理找不到方法的情况。本文深入剖析了objc_msgSend的动态解析和消息转发过程,阐述了消息查找、方法选择、对象转发等核心概念。通过掌握这些机制,开发者可以更深入地理解iOS消息机制,从而提升开发功底,编写出更加健壮和灵活的代码。