复杂度高的项目系统,我惯于花时间梳理出大手稿,作为参考,根据这个思路,我花时间对于OC底层的机制进行梳理,产出大手稿若干。
第四篇:msgSend 全流程
从调用msgSend到最后崩溃,涉及多个流程:
- cache_t 缓存的查找
- 类结构中去查找
- 动态方法决议
- 消息的快速转发
- 方法签名
未完成!NFY Not finished yet.
图画完了,文字版本,值写了 四五 亮点,123三点觉得很简单,先不写了。
1. cache_t 缓存的查找
2. 类结构中去查找
3. 动态方法决议
4.0 快速转发 的研究准备
随便走一个崩溃断点,LLDB 打 image list
找到 CoreFoundation 的地址,找到可执行的unix文件,然后使用 Hopper,打开 unix 文件,
4.1 快速转发
当完成了第三步的 impLookupOrForwarding 最后的 resolve 之后,如果返回的是 forwardingIMP,就会调用对象的
- (id)forwardingTargetForSelector:(SEL)aSelector;
官方文档这里说的清楚:
1 | 如果一个对象实现(或继承)此方法,并返回一个非nil(和非self)结果,则返回的对象将用作新的接收方对象,消息分派将恢复到该新对象。(显然,如果从该方法返回self,代码将陷入无限循环中。) |
也就是说如果你返回了一个对象A,那么就重新跟A来走整个这篇的流程。
如果这个方法你还是没有返回一个背锅的对象,还是没有找到的话,则进入最后的一次挽救机会,下一段落。
5. 方法签名
调用这个 methodSignatureForSelector
,然后对这个aSelector进行签名,如果返回Nil,就报错: Unrecognized selector
,如果处理了就按照如下的方法进行签名,需要写上 typeCoding。
forwardInvocation
方法调用之后,走了方法内部的东西之后,就真的再也不处理了,就这样了。
1 | - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{ |
无论在forwardInvocation方法中是否处理invocation事务,程序都不会崩溃。
- Post link: http://yangzai360.top/2020/11/05/OCBigManuscript04_msgSend/
- Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.