iOS消息转发

作者: 小罗哦吧 | 来源:发表于2019-02-20 15:41 被阅读0次

1.在说消息转发前需要先理解objc_magsent, objc_msgSend函数会依据接收者与选择子(SEL)的类型来调整适当的方法。为了完成此操作,该方法需要在接收者所属的类中搜寻其“方法列表”如果能找到与选择子名称相符的方法,就调整至其代码,如果找不到,就沿着继承体系继续向上查找,等找到合适的方法之后在跳转,如果还是找不到相符合的方法那就执行消息转发

2.上面是消息转发的条件消息转发包括一下:

1.动态方法解析(+ (BOOL)resolveInstanceMethod:(SEL)selector)他的作用是 类是否新增实力方法处理选择子有返回yes没有No

2.备用接收者 (- (id)forwardingTargetForSelector:(SEL)aSelector) 如果1返回类NO就到2,2的作用是把消息转给其他接收者来处理消息 没有就返回nil

3.完整消息转发 (-(void)forwardInvocation:(NSInvocation *)anInvocation) 如果2返回nil 创建NSInvocation 对象 封装全部细节 消息派发系统把消息派给目标对象

举个例子 模拟下字典 为属性添加set get 方法

@interface EOCAutoDictionary : NSObject
@property(nonatomic,strong) NSString *string;
@property(nonatomic,strong) NSNumber *number;
@property(nonatomic,strong) NSDate *date;
@property(nonatomic,strong) id opaqueObject;
@end
#import "EOCAutoDictionary.h"
#import <objc/runtime.h>
@interface EOCAutoDictionary()
@property(nonatomic,strong) NSMutableDictionary *backingStore;
@end
@implementation EOCAutoDictionary
@dynamic string,number,date,opaqueObject;//这个是让用户自己实现get set 方法 
- (id)init{
    if (self = [super init]) {
        _backingStore = [NSMutableDictionary new];
    }
    return self;
}
+ (BOOL)resolveInstanceMethod:(SEL)selector{
    NSString *selectorString = NSStringFromSelector(selector);
    if ([selectorString hasPrefix:@"set"]) {
        class_addMethod(self,
                        selector,
                        (IMP)autoDictionarySetter,
                        "v@:@");
    }else{
        class_addMethod(self,
                        selector,
                        (IMP)autoDictionaryGetter,
                        "@@:");
    }
    
    return YES;
    
}

id autoDictionaryGetter(id self ,SEL _cmd){
    EOCAutoDictionary *typedSelf = (EOCAutoDictionary *)self;
    NSMutableDictionary *backingStore = typedSelf.backingStore;
    NSString *key = NSStringFromSelector(_cmd);
    return [backingStore objectForKey:key];
}
void autoDictionarySetter(id self ,SEL _cmd,id value){
     EOCAutoDictionary *typedSelf = (EOCAutoDictionary *)self;
     NSMutableDictionary *backingStore = typedSelf.backingStore;
    NSString *selectorString = NSStringFromSelector(_cmd);
    NSMutableString *key = [selectorString mutableCopy];
    [key deleteCharactersInRange:NSMakeRange(key.length-1, 1)];
    [key deleteCharactersInRange:NSMakeRange(0, 3)];
    NSString *lowercaseFirstChar = [[key substringToIndex:1] lowercaseString];
    [key replaceCharactersInRange:NSMakeRange(0, 1) withString:lowercaseFirstChar];
    if (value) {
        [backingStore setObject:value forKey:key];
    }else{
        [backingStore removeObjectForKey:key];
    }
    
}

外面调用

 EOCAutoDictionary *dict = [EOCAutoDictionary new];
    dict.date = [NSDate dateWithTimeIntervalSince1970:475372800];
    NSLog(@"date = %@",dict.date);

相关文章

  • iOS 消息发送与转发详解

    iOS 消息发送与转发详解 iOS 消息发送与转发详解

  • iOS理解Objective-C中消息转发机制附Demo

    iOS理解Objective-C中消息转发机制附Demo iOS理解Objective-C中消息转发机制附Demo

  • runtime系列文章总结

    《iOS Runtime详解(消息机制,类元对象,缓存机制,消息转发)》《消息转发机制与Aspects源码解析》《...

  • iOS消息转发

    title: “iOS消息转发”date: 2016-03-22 13:48:38tags: 消息转发这块,我学习...

  • ios 消息转发

    ios在类中,没有定义的函数,要走消息转发流程。如果不走消息转发流程,程序会奔溃。消息转发流程分四步调用。 第一步...

  • iOS 消息转发

    有时候我们常常看到一个cash 信息,意思是这个对象不存在这个方法,你向这个对象发送消息就会crash。 我们除了...

  • iOS 消息转发

    消息转发是Objective-C运行时的一个重要特性,具体表现是当调用一个不存在的方法时,并不会立马Crash,R...

  • ios — 消息转发

    概念 首先我们需要简单了解下,什么是oc的消息以及oc中的消息转发。先看一段简单的代码 oc中调用方法就是向对象发...

  • iOS消息转发

    类对象在接收到无法解读的消息时,会出现unrecognized selector sent to instance...

  • iOS消息转发

    消息转发的前提 在对象收到无法解读的消息时会触发消息转发 消息转发的过程 I. resolveInstanceMe...

网友评论

    本文标题:iOS消息转发

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