我知道运行时为消息提供了一个机会,如果在类或超类中找不到该方法的实现。它将通过将消息+ (BOOL)resolveInstanceMethod:(SEL)name
发送到对象的类来开始:此方法允许您在运行时将该方法添加到类中:如果此消息返回YES,则表示它可以重新发送消息。从+ (BOOL)resolveInstanceMethod:(SEL)name
返回NO,我认为会调用-(id)forwardingTargetForSelector:(SEL)aSelector
(并且不会调用dynamicMethodIMP
),但仍会调用dynamicMethodIMP
和返回值相同是。 Apple Doc说道。
如果方法返回NO,则Objective-C运行时将控制传递给方法转发机制(https://developer.apple.com/library/mac/releasenotes/Foundation/RN-FoundationOlderNotes/)
返回YES和返回No之间有什么不同
+ (BOOL)resolveInstanceMethod:(SEL)name
。
像这样的一段示例代码:
`void dynamicMethodIMP(id self, SEL _cmd) {
NSLog(@"%@ has added", NSStringFromSelector(_cmd));
}
+(BOOL)resolveInstanceMethod:(SEL)sel {
if (sel == @selector(mustHas)) {
class_addMethod([self class], sel, (IMP) dynamicMethodIMP, "v@:");
return NO;
}
return [super resolveInstanceMethod:sel];
}`
[obj mustHas];
答案 0 :(得分:0)
您正在阅读的文档来自10.5发行说明,但该特定声明不属于current documentation。
class_resolveInstanceMethod()
的实施实际上忽略了您的返回值。它只是检查你是否实现了+resolveInstanceMethod
,如果你有,则调用它,然后它查找原始选择器(只是为了缓存结果)。返回值唯一重要的是调试运行时。
无需猜测邮件转发的工作原理。这都是开源的。这是调用+resolveInstanceMethod
(runtime/objc-class.mm)的函数:
/***********************************************************************
* _class_resolveInstanceMethod
* Call +resolveInstanceMethod, looking for a method to be added to class cls.
* cls may be a metaclass or a non-meta class.
* Does not check if the method already exists.
**********************************************************************/
static void _class_resolveInstanceMethod(Class cls, SEL sel, id inst)
{
if (! lookUpImpOrNil(cls->ISA(), SEL_resolveInstanceMethod, cls,
NO/*initialize*/, YES/*cache*/, NO/*resolver*/))
{
// Resolver not implemented.
return;
}
BOOL (*msg)(Class, SEL, SEL) = (typeof(msg))objc_msgSend;
BOOL resolved = msg(cls, SEL_resolveInstanceMethod, sel);
// Cache the result (good or bad) so the resolver doesn't fire next time.
// +resolveInstanceMethod adds to self a.k.a. cls
IMP imp = lookUpImpOrNil(cls, sel, inst,
NO/*initialize*/, YES/*cache*/, NO/*resolver*/);
if (resolved && PrintResolving) {
if (imp) {
_objc_inform("RESOLVE: method %c[%s %s] "
"dynamically resolved to %p",
cls->isMetaClass() ? '+' : '-',
cls->nameForLogging(), sel_getName(sel), imp);
}
else {
// Method resolver didn't add anything?
_objc_inform("RESOLVE: +[%s resolveInstanceMethod:%s] returned YES"
", but no new implementation of %c[%s %s] was found",
cls->nameForLogging(), sel_getName(sel),
cls->isMetaClass() ? '+' : '-',
cls->nameForLogging(), sel_getName(sel));
}
}
}