消息转发流程

2018-09-12  本文已影响0人  kMarkdown

实例方法的流程

RunTime

一个方法的调用实际上就是SEL(方法名)通过Runtime找到IMP(方法执行体)

消息转发机制

在Objective C的方法调用过程中,我们提到了当无法响应一个selector时,在抛出异常之前会先进入消息转发机制。
在触发消息转发机制即forwardInvocation:之前,Runtime提供了两步来进行轻量级的动态处理这个selector.

这个方法提供了一个机会:为当前类无法识别的SEL动态增加IMP。
比如:最常见的可以通过class_addMethod

void dynamicMethodIMP(id self, SEL _cmd){/*...implementation...*/}

+ (BOOL) resolveInstanceMethod:(SEL)aSEL
{
    if (aSEL == @selector(resolveThisMethodDynamically))
    {
          class_addMethod([self class], aSEL, (IMP) dynamicMethodIMP, "v@:");
          return YES;
    }
    return [super resolveInstanceMethod:aSel];
}

Tips,这里的"v@:"表示方法参数编码,v表示Void,@表示OC对象,:表示SEL类型。

如果resolveInstanceMethod返回NO,则表示无法在这一步动态的添加方法,则进入下一步:


这个方法提供了一个机会:简单的把这个SEL交给另外一个对象来执行。

-(id)forwardingTargetForSelector:(SEL)aSelector{
    if (aSelector == @selector(dynamicSelector) && [self.myObj respondsToSelector:@selector(dynamicSelector)]) {
        return self.myObj;
    }else{
        return [super forwardingTargetForSelector:aSelector];
    }
}

如果上述两步都无法完成这个SEL的处理,则进入消息转发机制

消息转发机制

消息转发机制有两个比较重要的方法:

forwardInvocation: 具体的NSInvocaion

methodSignatureForSelector: 返回SEL的方法签名


这里不得不提一下两个类:

NSMethodSignature 用来表示方法的参数签名信息:返回值,参数数量和类型

NSInvocaion SEL + 执行SEL的Target + 参数值

通常,拿到NSInvocaion对象后,我们可选择的进行如下操作

修改执行的SEL

修改执行的Target

修改传入的参数

然后调用:[invocation invoke],来执行这个消息。



上一篇 下一篇

猜你喜欢

热点阅读