我是靠谱客的博主 个性苗条,最近开发中收集的这篇文章主要介绍09.04-消息发送,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

      • 1. 消息发送的本质
      • 2.消息发送流程
        • 1. _objc_msgSend
        • 2. CacheLookup (快查找,在缓存中查找方法)
        • 3. __objc_msgSend_uncached
      • 3. 消息慢查找(lookUpImpOrForward)
        • 1. 定义消息转发
        • 2. 把类和父类都实现了
        • 3. 当前类的方法列表中查找
        • 4. 父类中查找
        • 5. 找到方法 goto done
      • 4. 总结

1. 消息发送的本质

 		Person *p = [Person new];
//        Person *p = ((Person *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("Person"), sel_registerName("new"));
        
        [p test];
//      ((void (*)(id, SEL))(void *)objc_msgSend)((id)p, sel_registerName("test"));
// 		objc_msgSend (p,sel_registerName("test"));
  • 通过objc_msgSend(<#id#>, <#SEL, …#>)

第一个 receiver : 消息接受者
第二个 SEL : 方法名
后面跟着参数


2.消息发送流程

1. _objc_msgSend

  • objc-msg-arm64.s

_objc_msgSend 是消息发送的入口
在这里插入图片描述


2. CacheLookup (快查找,在缓存中查找方法)

  • 方法缓存查找

通过CacheLookup 去cache缓存中查找方法

  • 通过散列表来查找方法


如果在cache中 没有找到方法,就跳转到__objc_msgSend_uncached方法中


3. __objc_msgSend_uncached

  • 寻找没有被缓存的方法,在方法列表中查找


lookUpImpOrForward(obj, sel, cls, LOOKUP_INITIALIZE | LOOKUP_RESOLVER)
查找方法的实现(imp)或者消息转发
参数中有 obj , sel(方法名) , cls(类),查找的枚举


3. 消息慢查找(lookUpImpOrForward)

1. 定义消息转发

  • 如果没有找到消息,且没有实现消息解析,就会转发消息


2. 把类和父类都实现了

  • 为了当前类找不到方法后,可以去父类找方法


3. 当前类的方法列表中查找

  • 在当前类的方法列表查找,如果没有找到,把curClass变成父类

如果一直找到没有了父类,说明方法根本不存在,imp变成方法转发方法.


4. 父类中查找

整个for循环的可循环数-1

  • 在父类的cache中找方法
  • 如果找到了, goto done
    如果没有找到,重新开始循环,在方法列表中寻找没有要找的方法

5. 找到方法 goto done

把找到的方法放入缓存cache中
参数是cls , 就是最开始传入的参数
即使是父类中找到的方法,也会存储在当前类的缓存cache中


  • 如果没有找到,就会到方法解析环节

4. 总结

  1. 当执行方法时,转换成objc_msgSend
  2. 在汇编语言中, _objc_msgSend 是入口,方法会由 CacheLookup 方法去cache缓存中查找

如果找到了,就直接执行
如果没有找到,就会执行 __objc_msgSend_uncached 方法,从而转到C语言中的lookUpImpOrForward

  1. 从当前类的方法列表中查找

找到了就执行(返回IMP),且存入缓存
没找到就到父类的缓存中查找,然后再在方法列表中查找

  1. 知道再也没有父类了,执行方法解析
  2. 方法解析没用,就到方法转发

最后

以上就是个性苗条为你收集整理的09.04-消息发送的全部内容,希望文章能够帮你解决09.04-消息发送所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(66)

评论列表共有 0 条评论

立即
投稿
返回
顶部