美文网首页
消息发送机制&消息转发机制

消息发送机制&消息转发机制

作者: Colin_狂奔的蚂蚁 | 来源:发表于2018-06-23 21:03 被阅读80次

    消息发送机制&消息转发机制

    • 消息发送机制:使用了运行时的方式, 通过SEL快速查找IMP的过程.
    • 消息转发机制:IMP找不到,通过方法进行转发.
    消息转发机制图.png

    消息转发的三种方式:

    // 1、动态方法解析
     + (BOOL)resolveClassMethod:(SEL)sel OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
     + (BOOL)resolveInstanceMethod:(SEL)sel OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
     
     // 2、快速消息转发
     - (id)forwardingTargetForSelector:(SEL)aSelector OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
     
     // 3、标准的消息转发
     - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector OBJC_SWIFT_UNAVAILABLE("");
     - (void)forwardInvocation:(NSInvocation *)anInvocation OBJC_SWIFT_UNAVAILABLE("");
    

    测试代码:

    #import "ViewController.h"
    #import "Person.h"
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        Person *per = [Person new];
        [per run];
    }
    @end
    

    其它文件:

    ===================Person文件===================
    #import <Foundation/Foundation.h>
    
    @interface Person : NSObject
    - (void)run;
    @end
    
    
    #import "Person.h"
    #import <objc/message.h>
    #import "Animation.h"
    
    @implementation Person
    
    // 1.动态方法解析
    + (BOOL)resolveInstanceMethod:(SEL)sel {
        NSLog(@"sel = %@", NSStringFromSelector(sel));
        // 1.判断没实现方法, 就动态添加方法
        if (sel == @selector(run)) {
            // 2.动态添加方法
            class_addMethod(self, sel, (IMP)newRun, "v@:@");
            return YES;
        }
        return [super resolveInstanceMethod:sel];
    }
    
    void newRun(id self,SEL sel, NSString *str) {
        NSLog(@"---run起来了没有 %@--",str);
    }
    
    // 二.消息转发重定向
    - (id)forwardingTargetForSelector:(SEL)aSelector {
        NSLog(@"%@",NSStringFromSelector(aSelector));
        if (aSelector == @selector(run)) {
            return [[Animation alloc] init];
        }
        return [super forwardingTargetForSelector:aSelector];
    }
    
    // 三.生成方法签名.
    - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
        // 1. 转化字符串
        NSString *sel = NSStringFromSelector(aSelector);
    
        // 2.进行判断 手动生成签名
        if ([sel isEqualToString:@"run"]) {
            return [NSMethodSignature signatureWithObjCTypes:"v@:"];
        } else {
            return [super methodSignatureForSelector:aSelector];
        }
    }
    
    // 四.拿到方法签名配发消息
    - (void)forwardInvocation:(NSInvocation *)anInvocation {
        NSLog(@"-----%@",anInvocation);
        // 1.拿到这个消息
        SEL selector = [anInvocation selector];
        // 2.转发消息.
        Animation *anm = [[Animation alloc] init];
    
        if ([anm respondsToSelector:selector]) {
            // 调用这个对象,进行转发
            [anInvocation invokeWithTarget:anm];
        } else {
            [super forwardInvocation:anInvocation];
        }
    }
    
    // 五.抛出异常
    - (void)doesNotRecognizeSelector:(SEL)aSelector {
        NSString *selStr = NSStringFromSelector(aSelector);
        NSLog(@"这个-----%@---方法不存在", selStr);
    }
    
    @end
    ===================Animation文件===================
    #import <Foundation/Foundation.h>
    
    @interface Animation : NSObject
    - (void)run;
    - (void)eat;
    @end
    
    
    
    #import "Animation.h"
    
    @implementation Animation
    - (void)run {
        NSLog(@"%@---Animation--run", self);
    }
    - (void)eat {
        NSLog(@"%@---Animation--eat", self);
    }
    @end
    

    相关文章

      网友评论

          本文标题:消息发送机制&消息转发机制

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