oc消息转发机制

一、消息转发机制

在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

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容