美文网首页
OC中的消息转发过程

OC中的消息转发过程

作者: 董二千 | 来源:发表于2017-02-14 11:08 被阅读15次

消息转发

描述:如果类不能执行这个方法,会执行动态消息转发,如果该类还是不能动态的添加方法,则走完整的消息转发。分两步,第一步看看有没有其他类可以执行该方法,如果没有走第二步,将所有的细节封装到NSInvocation中,给接受者最后一次机会

演示:

动态消息转发

在一个类MessageObj中定义两个方法,testDynamicMethodForward一个有实现方法,start一个没有实现的方法,调用没有实现的方法,在动态消息转发的时候将这个方法hook到已经实现的方法上:

@interface MessageObj()
@end


@implementation MessageObj

//-(void)start{}
void testDynamicMethodForward(){
    printf("testDynamicMethodForward \n");
}

+(BOOL)resolveInstanceMethod:(SEL)sel {
    class_addMethod([self class], sel, (IMP)testDynamicMethodForward, "v@@:");
    return YES;
}
@end

打印如下:testDynamicMethodForward

完整的消息转发第一步

定义两个类,第一个类MessageObj有一个未实现的方法start,并且没有实现动态消息转发。第二个类OtherClass,有一个和第一个类中未实现的方法同名的方法start,在进行完整消息转发的第一步时,将MessageObj中未实现的方法hook到,OtherClass的同名方法start

OtherClass类

@interface OtherClass : NSObject

@end

@implementation OtherClass

-(void)start{
    NSLog(@"do some thing %@",[self class]);
}

@end

MessageObj类

@implementation MessageObj

//-(void)start{}

-(id)forwardingTargetForSelector:(SEL)aSelector {
    printf("%p \n",&aSelector);
    OtherClass *obj = [OtherClass new];
    return obj;
}

调用start方法

MessageObj *obj = [MessageObj new];
[obj start];

打印:do some thing OtherClass

完整消息转发的第二步

如果以上两步都失败了,就走到这里。定义两个类MessageObjOtherClassMessageObj中存在OtherClass的实例。当走到消息转发的第三步时,先进行方法重签名-(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector,再走最后的消息转发-(void)forwardInvocation:(NSInvocation *)anInvocation

OtherClass类

@interface OtherClass : NSObject

@end
@implementation OtherClass

-(void)start{
    NSLog(@"message transform third part %@",[self class]);
}

@end

MessageObj类

@implementation MessageObj


-(instancetype)init {
    if (self = [super init]) {
        otherClass = [OtherClass new];
    }
    return  self;
}


//-(void)start{}
//方法重签名
-(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
    NSMethodSignature *signature = [super methodSignatureForSelector:aSelector];
    if (!signature) {
        signature = [otherClass methodSignatureForSelector:aSelector];
    }
    return signature;
}
//最后的消息转发
-(void)forwardInvocation:(NSInvocation *)anInvocation {
    if (!otherClass) {
        [self doesNotRecognizeSelector:[anInvocation selector]];
    }
    [anInvocation invokeWithTarget:otherClass];
}

打印:message transform third part OtherClass

用途:

  • 在方法不能识别的时候做一些保护,防止crash
  • 调试的时候打印一些感兴趣的日志
  • 也可以hook系统的方法玩玩呀

相关文章

  • OC中的消息转发过程

    消息转发 描述:如果类不能执行这个方法,会执行动态消息转发,如果该类还是不能动态的添加方法,则走完整的消息转发。分...

  • OC中消息传递的过程及消息转发流程

    会先从缓存中查找,采用的是哈希查找,若缓存命中,执行对应函数,若未命中,则从当前类方法列表中查找; 从当前类方法列...

  • OC中的消息转发

    前言 我们知道OC是一门动态语言、它提供了一个RunTime库把代码中的类型检测、方法调用等一系列操作放到了运行期...

  • OC中的消息转发

    OC是消息型语言,OC中的方法调用实际上是消息的发送,编译器并不能决定程序真正执行的到底是哪段代码,这个工作,需要...

  • OC中的消息转发

      当我们给一个对象发送了一个没有的方法,系统会抛出异常并打印,[unrecognized selector se...

  • iOS消息转发机制

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

  • 提升复习方向

    1像oc的消息发送机制,大家都知道消息发送过程里有个消息转发过程,但是为什么会有消息转发呢?这个问题一问的话,估计...

  • OC中消息转发机制

    在编译期 消息传递的过程中向类发送了其无法解读的消息并不会报错,因为在运行期可以继续向类中添加方法,所以编译...

  • 简析OC的消息转发机制

    什么是消息转发?其实OC的方法调用就是消息转发的过程,比如创建一个名为Persion的类,调用alloc和init...

  • 个人对iOS OC 消息转发机制的基本原理理解

    关于OC的消息转发机制,是大部分面试官在面试过程中经常问到的问题。在此我整理了一下我对OC消息转发机制的理解。 ...

网友评论

      本文标题:OC中的消息转发过程

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