996
的生活持续了好久,期间项目组各种新项目,博客感觉要荒废,那把这段时间项目期间的大神分享拿来总结一下 ^_^
之前对于消息转发一直处于懵懂状态,因为平时用到的并不多,通过这个分享详细研究下~~~
参考文章ibireme
oc
中调用方法被称为发消息,消息转发就是当找不到接收者时会对消息转发给能响应的对象,转发的核心方法就是_objc_msgForward
正常情况下,我们运行时调用一个没有实现的方法会崩溃,我们通过
暂停程序运行,并在lldb中输入下面的命令:
call (void)instrumentObjcMessageSends(YES)
/tmp/msgSend-xxx
文件可以看到运行时发送的信息
resolveInstanceMethod
提供动态添加方法支持
|
|
- (id)forwardingTargetForSelector:(SEL)aSelector
转发消息返回响应者
|
|
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
返回方法签名,
|
|
如果上面的方法返回的方法签名为空,调用
doesNotRecognizeSelector
调用该方法后,系统会抛出异常
如果方法签名不为空,就会调用- (void)forwardInvocation:(NSInvocation *)anInvocation
|
|
到此为止,消息转发结束;
可以看出在运行时有以下几个核心方法
|
|
其中
两个是消息转发的核心方法,我们要保证返回的NSMethodSignature
不能为空,然后在forwardInvocation
中配置目标方法
下面举一个实例:
比如说我们正常开发项目实现了一个通用页面,我们只需要保证传进去的数据源符合HHTestMsgForwardView
这个protocol
就能正常使用,
但突然有一天,产品经理给一个类似页面添加一个特殊效果滚动时做一些特别的事情
我们首先要实现tableview
的UIScrollViewDelegate
中的方法,此时如果将这些方法放到通用页面中实现,那么别的地方使用的时候是没必要的,我们可以通过_objc_msgForward
将这一部分转发出来给适应需求的地方实现
可以看出scrollView
的代理事件已经被转发出来了.
戳这里看源码,以上只是简单的使用,后续还要更加深入研究。
学习计划:
1、开源库中的使用 YYWeakProxy
、IGListKit
、Aspects
、JSPatch
2、扩展实现一对多双向通信XMPPFramework
、GCDMulticastDelegate
学习需要深入参考的文章