//blog.sina.com.cn/s/blog\_71e456db0100w1bm.html这实质上这是当受person这个目标发送run这个信息。

先是感谢这几乎单篇文章针对性自之相助:
http://blog.csdn.net/mangosnow/article/details/36183535
http://blog.sina.com.cn/s/blog\_71e456db0100w1bm.html
http://book.51cto.com/art/201403/432146.htm
http://www.itqx.net/thread-2286-1-1.html
http://blog.csdn.net/c395565746c/article/details/8507008
点几乎首稿子都是以网上查看到的材料

经一个略例子来简单、通俗的亮一下呀是信转发以及怎样消息转发
率先,你要明白就有限独概念:
OC中调用方法就是往目标发送信息。
比如 :

通下,我们设经一个有些例子来概括、通俗的领悟一下啊是信转发和哪消息转发,希望看了就篇稿子时大家照面彻底的明白OC的信息。

[person run];


即实在就是当为person这个目标发送run这个信息。
那么问题来了,当run这个主意只有出定义尚无落实会晤什么呢?
纵使经的报错

率先,你要掌握这片独概念:

*** Terminating app due to uncaught exception 
'NSInvalidArgumentException'
, reason: '-[Person run]: unrecognized selector sent to instance
OC中调用方法就是向目标发送信息。

比如 :
[person run];
及时事实上这是于被person这个目标发送run这个消息。
这就是说问题来了,当run这个措施才发定义尚无兑现会晤怎么样也?
尽管藏的报错

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Person run]: unrecognized selector sent to instance

ok,前提已经说了了,我们就起查找这错误原因讲起。

首先,该办法以调用时,系统会翻这目标是否接受这信息(查看此看似产生没有来之主意,或者发没有出落实这个法。),如果无能够而就当非克之动静下,就会见调用下面就几乎单艺术,给您“补救”的时,你得预先了解呢几效仿防止程序crash的备选方案,我们即便运用就几乎单方案展开信息转发,注意一点,前无异仿方案实现后一致法方法就未会见履。如果就几乎学方案你都无召开处理,那么程序即使见面报错crash。

由只假设:比赛足球时,脚下有球的那么叫球员,如果他的岗位不便于射门或者他的球即将吃对方球员抢断,这时最是将球传出去,这里的圆球就是一定给信息。
方案一:

  • + (BOOL)resolveInstanceMethod:(SEL)sel
  • + (BOOL)resolveClassMethod:(SEL)sel

方案二:

  • – (id)forwardingTargetForSelector:(SEL)aSelector

方案三:

  • – (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector;
  • – (void)forwardInvocation:(NSInvocation *)anInvocation;

顶目前为止大家都知道呀是信转发了。下面就是说一下立几效仿方案是哪调用的。

第一,系统会调用resolveInstanceMethod(当然,如果是方式是一个近似措施,就见面调用resolveClassMethod)让您自己吧这办法增加实现。

俺们来拘禁一个例证:

率先,创建了一个Person类的靶子p,然后调用p的run方法,注意,这个run方法是无写实现的。

屏幕快照 2015-03-21 下午7.13.01.png

跻身Person类的.m文件,我实现了resolveInstanceMethod这个主意也我的Person类动态增加了一个run方法的落实。(什么是动态增加?其实就是是在程序运行的时刻让某类的之一方法增加实现。具体实现内容就是吧点的void
run 这个c函数。)

当外部调用[p
run]时,由于我们并未落实run对应之方式,那么网会调用resolveInstanceMethod让您去开片其它操作。(当然,你吧足以免做操作,只是以斯例子中,我耶run方法动态增加了落实。)

屏幕快照 2015-03-21 下午7.31.52.png

持续运行,程序走至了咱C函数的一些,这样程序没有了崩溃。

屏幕快照 2015-03-21 下午7.43.28.png

屏幕快照 2015-03-21 下午7.43.58.png

脚说一下次之法方法,forwardingTargetForSelector,这个点子返回您要中转信息的目标。

俺们随后是事例来讲,为了有利于演示消息转发,我们新建了一个汽车类Car,并且实现了Car的run方法。

屏幕快照 2015-03-23 下午1.59.09.png

现今自己非失对方案一之resolveInstanceMethod做任何处理,直接调用父类方法。可以看来,系统就过来了forwardingTargetForSelector方法,我们现在赶回一个Car类的实例对象。

屏幕快照 2015-03-23 下午1.56.19.png

接轨运行,程序即使来了Car类的run方法,这样,我们就是贯彻了信转发。

屏幕快照 2015-03-23 下午2.00.50.png

承我们的事例。如果我们无实现forwardingTargetForSelector,系统就是会见调用方案三底有限只法子methodSignatureForSelector和forwardInvocation

methodSignatureForSelector用来很成道签名,这个签名就是给forwardInvocation中之参数NSInvocation调用的。

开始我们如果找的错误unrecognized selector sent to
instance原因,原来就因methodSignatureForSelector这个法子被,由于没找到run对应的落实方式,所以回来了一个拖欠的方签名,最终致程序报错崩溃。

据此我们得开的是协调新建计签名,再在forwardInvocation中因故而要是转会的深目标调用这个相应的签,这样也促成了音转发。

屏幕快照 2015-03-23 下午2.34.56.png

至于转变签名的路”v@:”解释一下。每一个方法会默认隐藏两单参数,self、_cmd,self代表法调用者,_cmd代表是法子的SEL,签名类型就是用来描述是办法的归值、参数的,v代表回到回值为void,@表示self,:表示_cmd。

今昔我们返回最初,我们调用的是Person类的run方法,最终方法给Car类的靶子来领。这就是OC的信转发机制。

屏幕快照 2015-03-21 下午7.13.01.png

屏幕快照 2015-03-23 下午2.44.05.png

ok,前提已经说罢了,我们就算由寻找这荒唐原因讲起。
先是,该措施在调用时,系统会翻动此目标是否接受这信息(查看这类似产生没起之艺术,或者有没有来落实此方式。),如果不可知同时独自于无能够之景下,就会见调用下面就几个章程,给您“补救”的时机,你可以先知道啊几套防止程序crash的备方案,我们就是以就几个方案展开信息转发,注意一点,前同模仿方案实现后同样效仿方法就无见面实行。如果立刻几乎仿照方案你都未曾做拍卖,那么程序即使会报错crash。
起个如:比赛足球时,脚下有球的那么叫球员,如果他的职务不便宜射门或者他的球即将为对方球员抢断,这时最是拿球传出去,这里的球就是相当给信息。
方案一:

  • (BOOL)resolveInstanceMethod:(SEL)sel

  • (BOOL)resolveClassMethod:(SEL)sel

方案二:

  • (id)forwardingTargetForSelector:(SEL)aSelector

方案三:

  • (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector;

  • (void)forwardInvocation:(NSInvocation *)anInvocation;

到目前为止大家已经知晓啊是信转发了。下面就是说一下就几乎学方案是安调用的。
先是,系统会调用resolveInstanceMethod(当然,如果这个方法是一个近似方式,就会见调用resolveClassMethod)让你协调吧是办法增加实现。
俺们来拘禁一个事例:
率先,创建了一个Person类的对象p,然后调用p的run方法,注意,这个run方法是尚未写实现的。

1433227564908824.png

进去Person类的.m文件,我实现了resolveInstanceMethod这个点子吧本人的Person类动态增加了一个run方法的兑现。(什么是动态增加?其实就算是以程序运行的时光给某类的某部方法增加实现。具体贯彻内容就也面的void
run 这个c函数。)
当外部调用[p
run]时不时,由于我们从不兑现run对应的方,那么网会调用resolveInstanceMethod让您错过做有其他操作。(当然,你吗得以无开操作,只是于这事例中,我吧run方法动态增加了实现。)

1433227589571991.png

承运行,程序走及了咱C函数的一部分,这样程序没有了崩溃。

1433227601958845.png

1433227607707796.png

脚说一下次之模拟方法,forwardingTargetForSelector,这个措施返回您得中转信息的目标。
我们随后是事例来讲,为了方便演示消息转发,我们新建了一个汽车类Car,并且实现了Car的run方法。

1433227621544939.png

今天自家莫失对方案一底resolveInstanceMethod做其他处理,直接调用父类方法。可以观看,系统已赶到了forwardingTargetForSelector方法,我们现在回到一个Car类的实例对象。

1433227633902159.png

连续运行,程序就算赶来了Car类的run方法,这样,我们即便实现了音信转发。

1433227647543989.png

承我们的例证。如果我们无实现forwardingTargetForSelector,系统便会见调用方案三之星星单点子methodSignatureForSelector和forwardInvocation
methodSignatureForSelector用来挺成道签名,这个签名就是吃forwardInvocation中的参数NSInvocation调用的。
发端我们而摸的错误unrecognized selector sent to
instance原因,原来就因为methodSignatureForSelector这个措施吃,由于没找到run对应之兑现方式,所以回来了一个缺损的办法签名,最终促成程序报错崩溃。
据此我们要做的凡上下一心新建计签名,再以forwardInvocation中因故而如转会的杀目标调用这个相应的签署,这样啊兑现了信息转发。

1433227669873301.png

至于变更签名的档次”v@:”解释一下。每一个方法会默认隐藏两只参数,self、_cmd,self代表办法调用者,_cmd代表是主意的SEL,签名类型就是之所以来描述是法的归来值、参数的,v代表回到回值为void,@表示self,:表示_cmd。
现行咱们回来最初,我们调用的凡Person类的run方法,最终方法吃Car类的靶子来接受。这就算是OC的音信转发机制。

1433227681818073.png

1433227687542866.png

相关文章