美文网首页
iOS深刻理解消息转发机制

iOS深刻理解消息转发机制

作者: 达摩君 | 来源:发表于2017-04-07 21:42 被阅读57次
崩溃日志.png

       上面这段异常信息是由NSObject的“doseNotRecognizeSelector:” 方法所抛出的,此异常表明:消息接受者的类型是LJBDictionary, 而该接受者无法理解名为setStr的方法。
       消息转发分为2大阶段。第一阶段先征询接受者,所属的类,看是否能动态添加方法,以处理当前这个“未知的选择子”(unknown selector),这叫做“动态方法解析(dynamic method resolution)”。第二阶段涉及“完整的消息转发机制(full forwarding mechanism)”。如果运行期系统已经把第一阶段执行完了,那么接受者自己就无法再以动态新增方法的手段来响应包含该选择子的消息了。此时,运行期系统会请求接受者以其他手段来处理与消息相关的方法调用。这又细分为二小步。首先,请接受者看看有没有其他对象能处理这条消息。若有,则运行期系统又会把消息转给那个对象,于是消息转发过程结束,一切正常。若没有“备援的接受者”(replacement receiver),则启动完整的消息转发机制,运行期系统会把与消息有关的全部细节都封装到NSInvocation对象中,再给接受者最后一次机会,令其设法解决当前还未处理的这条消息。

动态方法解析

       对象在收到无法解读的消息后,首先将调用其所属类的下列类方法:
+ (BOOL)resolveInstanceMethod:(SEL)sel;
       该方法的参数就是那个未知的选择子,其返回值为Boolean类型,表示这个类是否能新增一个实例方法用以处理此选择子。在继续往下执行转发机制之前,本类有机会新增一个处理此选择子的方法。假如尚未实现的方法不是实例方法而是类方法,那么运行期系统就会调用另外一个方法"resolveClassMethod:"。
       使用这种办法的前提是:相关发放的实现代码已经写好,只等着运行的时候动态插在类里面就可以了。此方案常用来实现@dynamic属性。(详情见最后的demo)

备援接受者

完整的消息转发


消息转发全流程

消息转发

以完整的例子实现动态方法解析

       下面示范如何以动态方法解析来实现@dynamic属性。将属性声明为@dynamic,编译器就不会为其自动生成实例变量及存取方法了。
在LJBDictionary.h文件中

#import <Foundation/Foundation.h>

@interface LJBDictionary : NSObject

@property(nonatomic, copy) NSString *str;

@end

在LJBDictionary.m文件中

#import "LJBDictionary.h"
#import <objc/runtime.h>

@interface LJBDictionary ()

@property(nonatomic, strong) NSMutableDictionary *backingStore;

@end

@implementation LJBDictionary

@dynamic str;

- (instancetype)init
{
    self = [super init];
    if (self) {
        _backingStore = [[NSMutableDictionary alloc]init];
    }
    return self;
}

+(BOOL)resolveInstanceMethod:(SEL)sel{

    NSString *selectorString = NSStringFromSelector(sel);
    if ([selectorString hasPrefix:@"set"]) {
        class_addMethod(self, sel, (IMP)ljbDictionarySetter, "v@:@");
    } else {
        class_addMethod(self, sel, (IMP)ljbDictionaryGetter, "@@:");
    }
    return YES;
}
//getter函数
id ljbDictionaryGetter(id self, SEL _cmd) {

    LJBDictionary *typedSelf = (LJBDictionary *)self;
    NSMutableDictionary *backingStoe = typedSelf.backingStore;
    
    NSString *key = NSStringFromSelector(_cmd);
    return [backingStoe valueForKey:key];
}
//setter函数
void ljbDictionarySetter(id self, SEL _cmd, id value) {
    LJBDictionary *typedSelf = (LJBDictionary *)self;
    NSMutableDictionary *backingStore = typedSelf.backingStore;
    
    NSString *selectorString = NSStringFromSelector(_cmd);
    NSMutableString *key = [selectorString mutableCopy];
    //删除“ : ”
    [key deleteCharactersInRange:NSMakeRange(key.length - 1, 1)];
    //删除“set“
    [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];
    }
    
}
@end

在主控制器ViewController.m中:

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    LJBDictionary *dict = [[LJBDictionary alloc]init];
    dict.str = @"lijiangbo";
    NSLog(@"%@",dict.str);
}

@end

打印结果
2017-04-07 21:37:54.999 test[4420:8019277] lijiangbo

相关文章

  • iOS深刻理解消息转发机制

    上面这段异常信息是由NSObject的“doseNotRecognizeSelector:” 方法所抛出的,...

  • runtime系列文章总结

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

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

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

  • iOS面试-基础

    [toc] Runloop AutoReleasePool 多线程 响应者链 消息响应机制 消息转发机制 iOS内...

  • iOS 消息转发机制

    今天大概学习了下iOS的消息转发机制,还是挺有收获,在此做下笔记,以便后面温习。 1.iOS的消息转发机制原理如下...

  • iOS面试题总结(二)

    iOS面试题(二) 消息发送和转发机制,SEL和IMP 消息发送转载自黄龙辉消息发送和消息转发机制 在Object...

  • Runtime

    相关简单介绍 消息机制消息传递机制消息转发机制-动态添加方法消息转发机制-快速转发消息转发机制-慢速转发消息转发机...

  • iOS - 消息转发机制

    我们知道,OC是动态语言,所有的方法都会以消息的形式传递给对象,对象会根据方法的类型来进行实例方法或者类方法的选择...

  • 【iOS】消息转发机制

    1、动态方法解析 对象在收到无法处理的消息时,会调用下面的方法,前者是调用类方法时会调用,后者是调用对象方法时会调...

  • iOS消息转发机制

    OC消息转发 oc中的调用对象或者类不存在的方法,会执行一遍消息转发流程.消息转发主要包括4步 首先调用+ (BO...

网友评论

      本文标题:iOS深刻理解消息转发机制

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