objc_msgSend
的具体流程如下:
通过isa
指针找到所属类
查找类的cache
列表
为什么会有cache
列表呢
因为cache
列表会提高效率
经常用的方法放到一个一个表里查的更快
如果没有则下一步
查找类的方法列表
如果能找到与选择子名称相符的方法,
就跳至其实现代码
找不到
就沿着继承体系继续向上查找
如果能找到与选择子名称相符的方法
就跳至其实现代码
实在找不到执行消息转发
就像BUG
一样
找不到就甩锅给其他人
消息转发的流程如下
动态方法解析
先问接收者所属的类
你看能不能动态添加个方法来处理这个未知的消息
如果能
则消息转发结束
备用接收者
请接收者看看有没有其他对象能处理这条消息
如果有
则把消息转给那个对象
消息转发结束
消息签名
这里会要求你返回一个消息签名
如果返回nil
则消息转发结束
完整的消息转发
备胎都搞不定了
那就只能把该消息相关的所有细节都封装到一个NSInvocation
对象
再问接收者一次
快想办法把这个搞定了
到了这个地步如果还无法处理
消息转发机制也无能为力了
对象在收到无法解读的消息后
首先调用其所属类的这个类方法
1 | // selector : 那个未知的选择子 |
假如尚未实现的方法不是实例方法而是类方法, 则会调用另一个方法resolveClassMethod:
动态方法解析失败, 则调用这个方法
1 | // selector : 那个未知的消息 |
消息签名
备用接受者搞不定
这个方法就准备要被包装成一个NSInvocation
对象
在这里要先返回一个方法签名
1 | - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector |