博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS 开发消息转发
阅读量:6116 次
发布时间:2019-06-21

本文共 2063 字,大约阅读时间需要 6 分钟。

开发中常见的错误

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ViewController function]: unrecognized selector sent to instance 0x7fdd10d17e00'复制代码

这代表function 方法没有实现,常见于.h 声明了方法,但是.m没有实现,或者

[self performSelector:NSSelectorFromString(@"function")];复制代码

这种利用字符串生成方法的代码,

unrecognized selector sent to instance 0x7fdd10d17e00'原因是因为methodSignatureForSelector这个方法中,由于没有找到run对应的实现方法,所以返回了一个空的方法签名,最终导致程序报错崩溃 这些代码Xcode都不会抛出错误,OC会提供3次机会来挽救

方法一: 动态解析

声明替补方法

void function(id sf,SEL cd){        NSLog(@"%@",sf);        NSLog(@"%@",NSStringFromSelector(cd));}复制代码

进行动态方法解析 利用运行时给对象添加方法

+(BOOL)resolveInstanceMethod:(SEL)sel {    if (sel == @selector(function)) {        class_addMethod(self, sel, (IMP)function, "v@:");    }    return [super resolveInstanceMethod:sel];}复制代码

这样方法的执行被转发到替代方法中

方法二: 快速转发 再本实例找不到方法的实现,可以将消息转发到实现该方法的对象

实现方法的实例

@implementation Function-(void)function{    NSLog(@"do function");}@end复制代码

实现快速消息转发 该方法的返回值就是执行未找到方法的对象

-(id)forwardingTargetForSelector:(SEL)aSelector {     Function *fun = [[Function alloc]init];    if ([fun respondsToSelector:aSelector]) {        return fun;    }    return [super forwardingTargetForSelector:aSelector];}复制代码

这样fun 对象就会执行 -(void)function 方法

方法三: 标准消息转发

-(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{    if (aSelector == @selector(function)) {        return  [NSMethodSignature signatureWithObjCTypes:"v@:"];    }    return [super methodSignatureForSelector:aSelector];}-(void)forwardInvocation:(NSInvocation *)anInvocation{    SEL selector = [anInvocation selector];    Function *fun1 = [[Function alloc]init];    Function *fun2 = [[Function alloc]init];    if ([fun1 respondsToSelector:selector]) {        [anInvocation invokeWithTarget:fun1];    }    if ([fun2 respondsToSelector:selector]) {                [anInvocation invokeWithTarget:fun2];    }}复制代码

methodSignatureForSelector:用来生成方法签名,这个签名就是给forwardInvocation:中的参数anInvocation调用的。 方法三中我们自己新建方法签名,在forwardInvocation中用你要转发的那个对象调用这个对应的签名,这样也实现了消息转发。

方法二和方法三都是消息转发,方法二简单快速但是只能将消息转发给一个对象,方法三比较复杂速度慢但是可以将消息转发给多个对象

转载地址:http://clvka.baihongyu.com/

你可能感兴趣的文章
Lua学习笔记(8): 元表
查看>>
PHP经典算法题
查看>>
LeetCode 404 Sum of Left Leaves
查看>>
醋泡大蒜有什么功效
查看>>
hdu 5115(2014北京—dp)
查看>>
数据结构中常见的树(BST二叉搜索树、AVL平衡二叉树、RBT红黑树、B-树、B+树、B*树)...
查看>>
PHP读取日志里数据方法理解
查看>>
第五十七篇、AVAssetReader和AVAssetWrite 对视频进行编码
查看>>
Vivado增量式编译
查看>>
一个很好的幻灯片效果的jquery插件--kinMaxShow
查看>>
微信支付签名配置正确,但返回-1,调不出支付界面(有的手机能调起,有的不能)...
查看>>
第二周例行报告
查看>>
多线程条件
查看>>
黄聪:VMware安装Ubuntu10.10【图解】转
查看>>
Centos 6.x 升级openssh版本
查看>>
公式推♂倒题
查看>>
vue实现点击展开,点击收起
查看>>
如何使frame能居中显示
查看>>
第k小数
查看>>
构建之法阅读笔记三
查看>>