近期在看SD的源码的时候,看到了下面这个写法:
id operations = operationDictionary[key];
if ([operations conformsToProtocol:@protocol(SDWebImageOperation)]){
[(id<SDWebImageOperation>) operations cancel];
}
可能是我代码看的还不够多,对于这样[(id<SDWebImageOperation>) operations cancel]
的写法还是第一次见。(协议难道不都是和代理一起用的吗!!)于是好奇的我决定了解一下这种写法。
首先operations
是遵守<SDWebImageOperation>
协议的, operations
是id
类型的,它是从operationDictionary
中取出来的。通常情况下,它是一个SDWebImageCombinedOperation
类型的对象。(特殊情况也会是一个数组,里面还是一堆SDWebImageCombinedOperation
类型的对象,当然sd也做了处理,我就不细说了。)
�下面先看看<SDWebImageOperation>
这个协议:
@protocol SDWebImageOperation <NSObject>
- (void)cancel;
@end
很简单,就申明了一个方法。
再看看SDWebImageCombinedOperation
类:
@interface SDWebImageCombinedOperation : NSObject <SDWebImageOperation>
果然是遵守<SDWebImageOperation>
协议的。那么就应该能在他的.m文件找到- (void)cancel;
方法的实现。
果然,我们可以找到。
但是我把上面的代码去掉协议申明改成这样[operations cancel];
,还是能成功调用。原因就是在于当我们得到operations的时候,他已经是一个遵循<SDWebImageOperation>
协议的对象了。所以不管调用cancel的时候是否有写明,问题都不大。
现在还有最后一个疑问,为什么不直接在SDWebImageCombinedOperation
的.h文件中声明- (void)cancel;
方法,这样不就可以直接调用了而避开了协议吗。
大佬告诉我了:这样写的目的是为了方便。当有几十个类都要有- (void)cancel;
方法时候,如果不用协议方法,就需要在几十个类中都声明方法。而用协议,只需要遵守,就可直接开始实现了。
当然我仍有不服,那为什么不直接来个父类再继承呢。
大佬耐心说道:如果你已经开发一半,难道再新建父类吗。或者这么多类都是杂七杂八的,也不能都继承同一个类。
虽然觉得有道理,但感觉还是不太舒服。如果你看到这篇文章又有自己的理解,请告诉我。谢谢。