美文网首页
消息发送,消息转发

消息发送,消息转发

作者: ianCure | 来源:发表于2015-03-03 18:24 被阅读102次

    [receiver message];

    这一句的含义是:向receiver发送名为message的消息。

    运行 clang-rewrite-objcMyClass.m之后将上面这句话重写成C代码

    ((void(*)(id,SEL))(void*)objc_msgSend)((id)receiver,sel_registerName("message"));

    去掉干扰因素,实际上上面这句话实际上是:

    objc_msgSend(receiver,@selector(message));

    所以,像对象发送消息,最终大都会转换为objc_msgSend方法的调用

    为什么是大都呢?

    id objc_msgSend(id self,SEL _cmd,...)

    将一个消息发送给一个对象,并且返回一个值。

    其中,self是消息的接受者,_cmd是selector, ...是可变参数列表。

    当向一般对象发送消息时,调用objc_msgSend;当向super发送消息时,调用的是objc_msgSendSuper; 如果返回值是一个结构体,则会调用objc_msgSend_stret或objc_msgSendSuper_stret。

    objc_msgSend函数将在self的方法字典中找到SEL _cmd对应的函数,所以这里你可以看出来,方法名一样的函数的SEL也是一样的。

    由上面可以看出,由于我们传入的参数是SEL,然后再找对应的函数,所以我们可以在运行时添加SEL对应的函数,或者进行替换,

    具体可以通过重载resolveInstanceMethod方法进行实现

    +(BOOL) resolveInstanceMethod:(SEL) sel

    这是NSObject根类提供的类方法,调用时机为当被调用的方法实现部分没有找到,而消息转发机制启动之前的这个中间时刻。

    这时就进行到消息转发的步骤了,具体步骤是:

    当被调用的方法实现部分没有找到,调用resolveInstanceMethod

    但是resolveInstanceMethod方法中也没有做重定向处理时,调用

    - (id)forwardingTargetForSelector:(SEL)sel

     { return _otherObject; }

    假如再不行,进入完整的消息转发流程,调用- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector

    - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector

    {

    NSMethodSignature *signature = [super methodSignatureForSelector:aSelector];

    if (signature == nil) {

    signature = [OtherObj instanceMethodSignatureForSelector:aSelector];

    }

    return signature;

    }

    如果signature为nil,则调用- (void)doesNotRecognizeSelector:(SEL)aSelector

    - (void)doesNotRecognizeSelector:(SEL)aSelector

    {

    NSLog(@"%@ %@",NSStringFromClass(self.class),NSStringFromSelector(_cmd));

    }

    如果不为nil,即other实现了这个函数,则调用

    (void)forwardInvocation:(NSInvocation *)anInvocation,实现完整转发流程大概实现如下图

    -(void)forwardInvocation:(NSInvocation *)invocation

    {

    SEL invSEL = invocation.selector;

    if([someOtherObject respondsToSelector:invSEL])

    [anInvocation invokeWithTarget:someOtherObject];

    }else{

    [self doesNotRecognizeSelector:invSEL];

    }

    }

    相关文章

      网友评论

          本文标题:消息发送,消息转发

          本文链接:https://www.haomeiwen.com/subject/tnjmxttx.html