多重代理的实现原理

2016-01-31

什么是多重代理

多重代理即代理集,是指用一个对象拥有实现多个对象的不同功能的能力。

普通(传统)的代理的实现方式,都是一对一的,而多重代理是一对多的。

Objective-c中,我们经常使用delegate去做对象之间的通信,普通的delegate对象一般都是对象之间是一对一的关系通信。而在有些项目需求中,我们希望能够让delgate对象拥有多种能力,比如说,在某一代理方法中,让delegate对象同时进行 “唱歌” 和 “跳舞”。举这个例子我在这里仅仅是说明它的原理,不会在代码中体现。我们可以把它封装在一个类里面 ,降低代理的耦合性,有利于维护代码。

多重代理的原理

代理集的原理是利用runtime中的消息转发机制实现的。消息转发机制在这里仅仅简单介绍,具体请 参考苹果开发文档或者谷歌。
我们都知道,在OC中,调用一个对象的方法,其实是给这个对象发送一条消息,当这条消息(或者这个方法)在它的类中,没有找到这个方法,则继续向父类寻找,一旦找到这个方法,就去执行对应的方法实现IMP,如果,还是没有找到,就会去执行其他步骤, step:1,动态方法解析,如果你是动态的实现了这个方法,就不会去执行下面的步骤即2,否则,执行步骤2;2,消息转发,又要分两小步;具体见图片(来源网络):

消息转发机制流程图

实现多重代理

在这里我封装了一个类MuiltipleProxyManager,就直接介绍如何使用这个类。

AS_SINGLETON(MuiltipleProxyManager); 是产生一个单例对象;

-(void)addDelegate:(id)object andRefreshDelegateBlock:(MuiltipleProxyManagerRefreshDelegateBlock)block;

增加一个对象到代理集中,如果这个对象,在代理集中存在,或者是[object isKindOfClass:[value class]]为真,将会移除代理集中的对象,把这个对象添加进去。始终让代理集中存储最新的对象;

-(void)addDelegates:(id)objects andRefreshDelegateBlock:(MuiltipleProxyManagerRefreshDelegateBlock)block;增加一组对象到代理集中,objects可以是NSArray,NSMutableArray,NSDictionary,NSMutableDictionary,注意,如果是 字典,键值 必须是 id key = [NSString stringWithFormat:@"%p",obj]; 产生的;

-(void)removeDelegate:(id)object; 从代理集中移除一个object

-(void)removeDelegates:(id)objects; 从代理集中移除多个object

-(void)removeAllDelegates; 从代理集中全部移除对象;

默认的存储方式是MuiltipleProxyManagerDelegateTargetsTypeArray,如果要改变存储方式,可以通过设置属性delegateTargetsType. 注意,在向集合中添加对象时,需要更新代理,拿本例说明,

__block MuiltipleProxyManager *__weak weakProxy = proxy;

1
2
3
4
5
6
[weakProxy addDelegates:dic andRefreshDelegateBlock:^{

scrollView.delegate = nil;//必须这样,不知道原因,否者有bugs

scrollView.delegate = (id)weakProxy;
}];

小结

这个项目的工程在github上:https://github.com/woodjobber/MuiltipleProxyManager

Bugs反馈:`woodjobber@outlook.com`

微信公众号:嘀咕嘀咕(iOSSharers)

扫二维码关注