据我了解,未实现的方法通过以下方式解决:
- resolveInstanceMethod: /resolveClassMethod: 获得实现方法的机会
- forwardingTargetForSelector:有机会转发给委托人
- forwardInvocation: 有机会处理它认为合适的方法。
这个三步过程在哪里定义?我想自己处理它,因为 NSInvocation 可能对我的需求来说太重了。我已经在运行时源上戳了一下,但实际上什么也看不到。
看起来旧的运行时会在接收器上调用 forward:args: 来执行此操作,但这似乎已经从新的运行时消失了。我猜这个过程必须由框架而不是运行时定义,因为如果运行时依赖 Cocoa 到需要 NSInvocation 来处理消息的程度,那就很奇怪了。它可能是在 NSObject / NSProxy 上调用的未记录方法吗?
编辑:
看起来运行时声明但从未定义一个 C 函数,当 objc_msgSend 找不到实现时调用该函数:
id objc_msgForward(id object,SEL message,...);
我不为 Apple 工作,所以我不知道 Foundation 如何实现这一点,但至少在 Cocotron 的情况下,他们使用:
id objc_msgForward(id object,SEL message,...)
{
Class class=object->isa;
struct objc_method *method;
void *arguments=&object;
if((method=class_getInstanceMethod(class,@selector(forwardSelector:arguments:)))!=NULL)
return method->method_imp(object,@selector(forwardSelector:arguments:),message,arguments);
else
{
OBJCRaiseException("OBJCDoesNotRecognizeSelector","%c[%s %s(%d)]", class_isMetaClass(class) ? '+' : '-', class->name,sel_getName(message),message);
return nil;
}
}
添加一个forwardSelector:arguments:
方法似乎不起作用,所以我猜这是 Cocotron 特有的。有人知道objc_msgForward
Foundation是做什么的吗?