更多文章请点击下方:
源码分析
动态方法解析没有找到,会进入接下来消息转发过程
// No implementation found, and method resolver didn't help.
// Use forwarding.
imp = (IMP)_objc_msgForward_impcache;
cache_fill(cls, sel, imp, inst);
这个时候是进入汇编底层
/********************************************************************
*
* id _objc_msgForward(id self, SEL _cmd,...);
*
* _objc_msgForward is the externally-callable
* function returned by things like method_getImplementation().
* _objc_msgForward_impcache is the function pointer actually stored in
* method caches.
*
********************************************************************/
STATIC_ENTRY __objc_msgForward_impcache
MESSENGER_START
nop
MESSENGER_END_SLOW
// No stret specialization.
b __objc_msgForward 进行消息转发
END_ENTRY __objc_msgForward_impcache
从动态方法解析到消息转发这个过程只是汇编,苹果没有将此部分的代码开源,但是可以通过一个函数来查看整个Objective-C调用过程。
/***********************************************************************
* instrumentObjcMessageSends
**********************************************************************/
// Define this everywhere even if it isn't used to simplify fork() safety code.
spinlock_t objcMsgLogLock;
#if !SUPPORT_MESSAGE_LOGGING
void instrumentObjcMessageSends(BOOL flag)
{
}
调用的日志信息路径:Private/tmp/msgSend-123456
通过查看消息转发过程,主要有几个函数:
-
forwardingTargetForSelector 在这个函数里我们可以进行自定义处理、crash收集、预防崩溃
-
methodSignatureForSelector
-
forwardInvocation 在这个函数里可以打印系统调用堆栈并上传我们自己后台,如:友盟、bugly;method-swizzling;消息转 发
以上是消息转发的流程,如果未处理的话,系统就提示错误信息并且程序闪退
// Default forward handler halts the process.
__attribute__((noreturn)) void
objc_defaultForwardHandler(id self, SEL sel)
{
_objc_fatal("%c[%s %s]: unrecognized selector sent to instance %p "
"(no message forward handler is installed)",
class_isMetaClass(object_getClass(self)) ? '+' : '-',
object_getClassName(self), sel_getName(sel), self);
}
void *_objc_forward_handler = (void*)objc_defaultForwardHandler;