返回

iOS八股文(七)之objc_msgSend的动态解析和消息转发

IOS

在上一篇文章中,我们了解了objc_msgSend过程中消息查找的流程,其中有个查找方法的函数名叫lookUpImpOrForward,字面翻译为“查找方法或者转发”。那么本文就来记录下objc_msgSend的动态解析和消息转发。

动态解析

动态解析发生在类加载时,且只发生一次。动态解析过程如下:

  1. 消息发送时,首先判断方法是否已经解析过,即查看IMP指针是否为NULL,如果是,则执行动态解析。
  2. 动态解析时,会遍历当前类以及它的父类的Method List,寻找方法选择器对应的IMP指针,如果找到,则将IMP指针赋值给方法并返回。
  3. 如果在当前类以及其父类都没有找到对应的IMP指针,则会尝试调用resolver方法进行动态解析。
  4. 如果resolver方法返回YES,则会将解析后的IMP指针赋值给方法并返回。
  5. 如果resolver方法返回NO,则动态解析失败,objc_msgSend返回NULL

消息转发

消息转发发生在objc_msgSend动态解析失败时,消息转发流程如下:

  1. 当动态解析失败时,objc_msgSend会调用forwardingTargetForSelector方法,让对象有机会将消息转发给其他对象。
  2. 如果forwardingTargetForSelector方法返回nil,则objc_msgSend调用methodSignatureForSelector方法获取方法签名。
  3. 如果methodSignatureForSelector方法返回nil,则消息转发失败,objc_msgSend返回NULL
  4. 如果methodSignatureForSelector方法返回非nil,则objc_msgSend调用forwardInvocation:方法,将消息转发给其他对象。
  5. 如果forwardInvocation:方法执行成功,则消息转发成功,objc_msgSend返回YES
  6. 如果forwardInvocation:方法执行失败,则消息转发失败,objc_msgSend返回NULL

在iOS开发中,objc_msgSend函数扮演着至关重要的角色。它负责消息的发送和方法的调用,并提供了动态解析和消息转发等机制来处理找不到方法的情况。本文深入剖析了objc_msgSend的动态解析和消息转发过程,阐述了消息查找、方法选择、对象转发等核心概念。通过掌握这些机制,开发者可以更深入地理解iOS消息机制,从而提升开发功底,编写出更加健壮和灵活的代码。