一、消息转发机制
在OC中,调用一个对象的方法,实际上是给对象发了一条消息,在编译Objective-C函数调用的语法时,会被翻译成一个C的函数调用:objc_msgSend(),例如:
[array insertObject:foo atIndex:2];
//会被翻译成:
objc_msgSend(array, @selector(insertObject:atIndex), foo, 2);
以[object foo]为例:
通过object的isa指针找到它的class
在class的method_list中找到foo
如果class中没找到foo,则继续往他的superclass中查找
一旦找到foo这个函数,就去执行对应的方法实现(IMP)
如果一直没有找到foo,OC的runtime将继续下面的步骤:
二、动态方法决议与消息转发
在oc中,如果向一个对象发送一条该对象无法处理的消息(对应selector不存在),会导致程序crash, 但是,在crash之前,oc的运行时系统会先经过以下两个步骤:
Dynamic Method Resolution(动态方法决议)
Message Forwarding(消息转发)
Dynamic Method Resolution(动态方法决议)
让我们可以在程序运行时动态的为一个selector提供实现,如果我们添加了函数的实现,并返回YES,运行时系统会重启一次消息的发送过程,调用动态添加的方法
调用实例方法:- (BOOL)resolveInstanceMethod:(SEL)sel
调用类方法:+ (BOOL)resolveClassMethod:(SEL)sel
+ (BOOL)resolveInstanceMethod:(SEL)sel{
if (sel == @selector(foo)) {
class_addMethod([self class], sel, (IMP)dynamicMethodIMP, "V@:");
return YES;
}
return [super resolveInstanceMethod:sel];
}
void dynamicMethodIMP(id self, SEL _cmd){
NSLog(@"%s", __PRETTY_FUNCTION__);
}
class_addMethod(Class cls, SEL name, IMP imp, const char *types) ===> 动态添加方法
const char *types:
”v@:”这是一个void类型的方法,没有参数传入
“i@:”这是一个int类型的方法,没有参数传入。
”i@:@”这是一个int类型的方法,有一个参数传入。==> ''i@:*''
如果方法返回NO时,将会进入下一步:
Message Forwarding (消息转发)
先通 SEL查找:先调用:- (id)forwardingTargetForSelector:(SEL)aSelector ,通过aSelector进行查找方法名,返回对象。
### ProxyDispatcher.h
@interface ProxyDispatcher : NSObject
- (void)Func;
@end
### ProxyDispatcher.m
- (id)forwardingTargetForSelector:(SEL)aSelector{
if (aSelector == @selector(Func)) {
return [DispatcherObject new];
}
return nil;
}
### DispatcherObject.m
- (void)Func{
NSLog(@"%s", __PRETTY_FUNCTION__);
}
后通过 签名查找: - (NSMethodSignature )methodSignatureForSelector:(SEL)aSelector *SEL查找失败(返回nil或self)
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{
NSMethodSignature *methodSignature = [super methodSignatureForSelector:aSelector];
if (!methodSignature) {
methodSignature = [NSMethodSignature signatureWithObjCTypes:"v@:*"];
}
return methodSignature;
}
消息转发流程图:

参考引用:http://www.cocoachina.com/ios/20151208/14595.html
网友评论