美文网首页
iOS的消息转发机制

iOS的消息转发机制

作者: StonesMonkey | 来源:发表于2017-05-26 16:47 被阅读150次

这里讲的是消息转发机制,如果对象收到无法解读的消息之后会发生什么情况?
我们都知道Objective-c是谁一种动态语言,我们说App运行它要经历两个过程,分别说编译阶段和运行阶段。编译阶段编译器只会判断程序中有没有这个方法,而不会去十分准确的去判断这个方法是否属于调用的对象。如图1

图1:unrecognized selector sent to instance

在编译阶段,编译器对无法解读的方法无法确定对错,毕竟我们都知道我们可以动态的给对象增加方法,当对象接受到无法解读的方法后,就会启动“消息转发(messafe forwarding)”机制,程序经由此过程告诉对象应该如何处理未知消息<这段话来自effective Object - C 2.0>

消息转发流程

图1:消息转发流程图

图片来源于:
http://www.cnblogs.com/ansyxpf/p/5690215.html

要点:

  • 1.越到后面消息处理所消耗的资源越大,最好能在第一步就完成,这样的话运行期间就会将方法缓存起来
  • 2.注意,这个消息转发流程是,当当前类到基类整个过程都没有找个这个方法的时候才会调用消息循环。
    + 3.通过流程图我们可以看出,我们可以在任何一个步骤动态的给期添加方法属性让方法执行,也可以不做处理让程序不carsh

+ (BOOL)resolveInstanceMethod:(SEL)sel

在SMPerson.m方法里面实现这个方法并打印

<pre>
//#import "SMPerson.h"
@implementation SMPerson
// 不让它生成setter和getter方法
@dynamic name;
+ (BOOL)resolveInstanceMethod:(SEL)sel {
NSLog(@"%s",func);
return [super resolveInstanceMethod:sel];
}
@end

// 是为了好看,复制的时候可以去掉
</pre>

图2: 它会调用__fun__

当启动消息转发机制,首先会到<code>+ (BOOL)resolveInstanceMethod:(SEL)sel</code>它是动态给选择器提供一个实现,如果它返回YES,那么会有对这个方法处理的对象,如果返回NO,将跳到下一个消息,去寻找这个方法的处理者。
<code>所以为了让我们的方法得到处理我们可以通过运行时动态给他添加方法</code>

在这个方法动态添加方法

我们都知道,出现的问题是,我们调用的这个setName方法,不存在,那么问题就好解决了,我们添加一个这个方法就好了

<pre>

  • (BOOL)resolveInstanceMethod:(SEL)sel {

    NSString *selStr = NSStringFromSelector(sel);
    // 如果是set方法
    if ([selStr hasPrefix:@"set"]) {

      /**
          第一个参数: 填入当前方法
          第二个参数: 要执行的方法名称
          第三个参数: 这个类调用的C语言方法
          第四个参数: 方法的形式
       */
      class_addMethod([self class], sel, (IMP)AutoDictionarySetter,"v@:@");
      return YES;
    

    } else { // 如果它不是setter方法这里默认就认为是getter方法
    // 增加getter方法
    class_addMethod([self class], sel, (IMP)AutoDictionarygetter, "@@:");
    return YES;
    }
    return NO;
    }
    </pre>

setter 方法 和getter方法添加的c语言实现

<pre>
void AutoDictionarySetter(id self, SEL _cmd, id vaule) {

NSString *selStr = NSStringFromSelector(_cmd);
// 消除set方法的点和set
NSMutableString *key = [selStr mutableCopy];
[key deleteCharactersInRange:NSMakeRange(key.length - 1, 1)];
[key deleteCharactersInRange:NSMakeRange(0, 3)];
// 让它变成小些
NSString *lowSrr = [[key substringFromIndex:0] lowercaseString];
[key replaceCharactersInRange:NSMakeRange(0, 1) withString:lowSrr];

if (vaule) {
    
    [dictStore setValue:vaule forKey:key];
}else {
    
    [dictStore removeObjectForKey:key];
}

}
id AutoDictionarygetter(id self, SEL _cmd) {

NSString *key = NSStringFromSelector(_cmd);
return [dictStore objectForKey:key];

}
</pre>

当我们给当前类动态的补充了这个方法,然后返回YES ,根据图1消息转发所示 返回YES,消息已经被处理,当返回NO的时候呢?

备缓接受者

上面提到,当<code> resolveInstanceMethod </code>接收不到数据的时候,

相关文章

  • 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

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

  • 深入了解runtime

    iOS经典讲解之[self class]和[super class]的区别 iOS的消息机制和消息转发 Objec...

  • iOS - 消息转发机制

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

  • 【iOS】消息转发机制

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

  • iOS消息转发机制

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

网友评论

      本文标题:iOS的消息转发机制

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