Objective-C 消息发送完整流水线:从 cache 命中到崩溃

快速路径
慢速查找
动态解析
消息转发
崩溃
点击节点查看源码
入口
objc_msgSend(id self, SEL op, ...)
ARM64 汇编入口 · Messaging.s / objc-msg-arm64.s
self == nil ?
↓ no
快速路径 Fast Path
cache_t::lookup(SEL)
bucket_t 线性探测 · cache_t.h / cache_t.mm
✓ Cache Hit
直接 br x17 跳转 IMP
零额外开销
IMP 执行 → return
消息发送完成
✗ Cache Miss
跌入 __objc_msgSend_uncached
进入慢速路径
慢速路径 Slow Path
lookUpImpOrForward(obj, sel, cls, ...)
objc-runtime-new.mm:7672 · C++ 层核心查找
加锁 runtimeLock
method_array_t 线性 / 二分查找
class_rw_t → methods → sorted bisect_key
未找到 → 爬 superclass 链
✓ 找到 Method
log_and_fill_cache()
写入 cache_t → 返回 IMP
IMP 执行 → return
填充缓存,下次直达
✗ 全链遍历无果
返回 _objc_msgForward_impcache
进入动态解析
动态解析 Dynamic Method Resolution
resolveMethod_locked(inst, sel, cls, ...)
objc-runtime-new.mm · 最多触发一次
+resolveInstanceMethod: / +resolveClassMethod:
用户实现 class_addMethod()
重新走 lookUpImpOrForward
解析失败 / 未实现
resolver = NO
进入转发流程
消息转发三部曲 Message Forwarding
① forwardingTargetForSelector:
Fast Forwarding · 返回替代接收者对象
✓ 返回非 nil / self
重新向新对象发送消息
消息发送重启
✗ 返回 nil / self
进入完整转发
② methodSignatureForSelector:
Full Forwarding 第一步 · 返回 NSMethodSignature
✓ 签名有效
构造 NSInvocation 对象
进入步骤 ③
✗ 返回 nil
运行时记录警告
直接崩溃
③ forwardInvocation:(NSInvocation *)
Full Forwarding 第二步 · 完全控制权交给用户
✓ 自行处理
invoke / 路由 / 吞掉消息
✗ 调用 [super forwardInvocation:]
NSObject 默认实现 → doesNotRecognizeSelector:
崩溃 Crash
doesNotRecognizeSelector: → 异常 / _objc_fatal
unrecognized selector sent to instance 0x... ‖ EXC_BAD_INSTRUCTION / SIGABRT