在上一篇文章iOS协议使用的一些理解中,我记录了自己对协议的一些新的理解。在评论区中,前辈席萍萍Brook_iOS深圳有提到:
代理只是协议使用的一小部分。
其实当时对于这个结论还是半信半疑,因为我对代理的认识是从消息传递开始。
当时看的博客有使用代理的示例,自己跟着写起来,发现这样写确实可以实现需求。然后在我学会block之前,总是这样写:
1.A类中先写个协议 @protocol
2.A类中再写个delegate属性 并需要遵守协议
3.在B类中设置 obj.delegate = self
4.在B类中实现protocol的方法
5.A类调用B类实现的方法
总认为这样是理所当然的,这样是没有错误的,甚至自以为是的认为协议就是要和代理一起使用。没有深入去思考为什么这样写。
终于,在前辈的提示之下,我开始深思这个代理设计模式。下面我记录下我的理解。
其实在盲目使用代理的同时,类似代理的写法我也用的不少,只是懵懵懂懂罢了。
还记得动画实战:自定义下拉刷新控件这篇文章中,自定义的刷新控件为了时刻获得控制器中的tableView
的contentOffset
属性,我将tableView
作为属性赋值给了自定义刷新控件。
self.rhv = [tableView attachRefreshHeadViewWithTarget:self action:@selector(reloadData)];
这样就能在控件内部监视tableView
的contentOffset
属性变化。
虽然这样的写法看上去和代理不那么类似,但是都是将对象作为属性赋值。代理的obj.delegate = self
不也是类似吗。
同时,我也给该控件设置了target
属性和action
属性。在需要做刷新的时候直接让target
调用action
。(实则让控制器刷新数据)
[self.target performSelector:self.action];
这样的写法不也和代理模式类似吗。
再反观代理设计模式,定义协议,遵守协议,实现协议方法,调用方法。多了的步骤就是和协议相关的步骤。但是为什么要这么写呢。
高效 安全
先说高效,当多个类都需要实现相同方法的时候,用协议更高效。因为只需要遵守协议即可。
再说安全,当我们调用代理方法的时候,往往会这样写:
if ([self.delegate respondsToSelector:@selector(vcFoo:)]) {
[self.delegate vcFoo:@""];
}
或者这样:
if ([operations conformsToProtocol:@protocol(SDWebImageOperation)]){
[(id<SDWebImageOperation>) operations cancel];
}
都会去判断一下是否能调用,这样就不会出现找不到方法导致奔溃的现象了。
以上算是我的心路历程,也只是记录我的理解。如果刚好看到了,有更好的理解也欢迎指出,如果你觉得很乱的话,就不要再去深思我写的内容了。