美文网首页
iOS--浅谈消息转发机制

iOS--浅谈消息转发机制

作者: 叫我龙哥 | 来源:发表于2021-10-18 17:27 被阅读0次

iOS--浅谈消息转发机制

相信大家对这句话unrecognized selector sent to instance 0x*********一点都不陌生吧。

下面就来简单说一下 拯救即将崩溃代码--iOS的消息转发

动态绑定引发

因为OC是一个动态运行时语言,其中之一的特性就是动态绑定。

关于动态绑定,苹果官网的给的解释为:(determining the method to invoke at runtime)。

简单点来说就是:程序直到执行时才能确定实际要调用的方法。

这样就会造成一个问题,我可以向一个实例发送一个消息,让它执行一个不属于自己的方法。这个时候就会出现unrecognized selector sent to instance

如果发生这种情况,那么我们就可以应用消息转发来解决这个问题。把这个不属于自己的方法变成属于自己的方法,或者找一个有这个方法的实例来执行这个方法。

在程序抛出这个错误之前我们有三次可以修正这个错误的机会。

拯救即将崩溃代码

第一步 方法解析处理阶段 | 动态方法决议

该方法内可为当前类动态添加方法。

将sel的方法实现指向一个已存在的方法


/**
 方法解析处理阶段 | 动态方法决议
 该方法内可为当前类动态添加方法。
 将sel的方法实现指向一个已存在的方法
 */
+ (BOOL)resolveInstanceMethod:(SEL)sel
{
    NSString *selectorString = NSStringFromSelector(sel);
    printf("%s %s\n", __func__, selectorString.UTF8String);
    
    // 根据 sel 得到 class 的实例方法
    Method method = class_getInstanceMethod([self class], @selector(dynamic_method));
    // 根据 sel 得到 class 的函数指针
    IMP method_imp = class_getMethodImplementation([self class], @selector(dynamic_method));
    // 给找不到实现的sel添加实现
    BOOL ret = class_addMethod([self class], sel, method_imp, method_getTypeEncoding(method));
    printf("%s\n", ret?"交换添加成功":"交换添加失败");
    // 返回结果不影响流程
    return YES;
}

第二步 快速转发阶段 | 快速查找

上一步未解决问题时触发。

返回一个能响应aSelector的实例,即将aSelector转发给另外的类。

/**
 快速转发阶段 | 快速查找
 上一步未解决问题时触发。
 返回一个能响应aSelector的实例,即将aSelector转发给另外的类。
 */
- (id)forwardingTargetForSelector:(SEL)aSelector
{
    NSString *selectorString = NSStringFromSelector(aSelector);
    printf("%s %s\n", __func__, selectorString.UTF8String);
    
    if ([selectorString isEqualToString:@"no_imp_method"]) {
        // 返回一个实现了aSelector函数的实例
        // 如果该实例没有实现aSelector,则进入下一步methodSignatureForSelector
        printf("%s 转发消息至BackUpClass\n",__func__);
        return  [[BackUpClass alloc] init];
    }
    // 返回self或者nil,则说明没有可以响应的目标,则进入下一步methodSignatureForSelector。
    return nil;
}

第三步 常规转发阶段 | 慢速查找

获得一个方法签名。签名由一个能响应aSelector的实例生成。
有签名则进入消息转发的最后一步forwardInvocation。

/**
 常规转发阶段 | 慢速查找
 返回一个方法签名。签名由一个能响应aSelector的实例生成。
 
 */
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
    NSString *selectorString = NSStringFromSelector(aSelector);
    printf("%s %s\n", __func__, selectorString.UTF8String);
    
    BackUpClass * backUp = [BackUpClass new];
    NSMethodSignature * sign = [backUp methodSignatureForSelector:aSelector];
    //有签名则进入消息转发的最后一步forwardInvocation
    return sign;
}

也可以什么都不处理,至此本次消息转发结束,程序也不会crash。

/**
 将sel转发给一个真正实现了sel的对象
 也可以什么都不处理,至此本次消息转发结束,也不会crash。
 */
- (void)forwardInvocation:(NSInvocation *)anInvocation
{
    printf("%s %s\n",__func__ , anInvocation.description.UTF8String);
    
    // 创建备用消息接收对象
    BackUpClass * backUp = [[BackUpClass alloc] init];
    printf("%s 转发消息至BackUpClass\n",__func__);
    [anInvocation invokeWithTarget:backUp];
}

写在后面

浅谈。可以交流。

相关文章

  • iOS--浅谈消息转发机制

    iOS--浅谈消息转发机制 相信大家对这句话unrecognized selector sent to insta...

  • Runtime

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

  • runtime系列文章总结

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

  • iOS消息转发机制

    消息转发机制: 消息转发机制是相对于消息传递机制而言的。 1、消息(传递)机制 RunTime简称运行时。就是系统...

  • 《Effective Objective-C 2.0 》 阅读笔

    第12条:理解消息转发机制 1. 消息转发机制 当对象接收到无法解读的消息后,就会启动“消息转发”机制,开发者可经...

  • (十二) [OC高效系列]消息的派发机制

    1.什么是消息转发机制 消息转发机制是在调用未知方法时出现的 消息转发机制让程序员有机会去处理未知方法 消息转发机...

  • 消息转发机制(动态消息转发)

    例子分析 1)在给程序添加消息转发功能以前,必须覆盖两个方法,即methodSignatureForSelecto...

  • 深入理解Object-C消息转发机制

    深入理解Object-C消息转发机制 深入理解Object-C消息转发机制

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

    消息发送机制&消息转发机制 消息发送机制:使用了运行时的方式, 通过SEL快速查找IMP的过程. 消息转发机制:I...

  • 消息转发机制

    为什么说 OC 的动态的 严格来说iOS中不存在方法调用的说法,应该说是消息的传递。消息传递和函数调用的区别就是,...

网友评论

      本文标题:iOS--浅谈消息转发机制

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