作者:ani_di
版权所有,转载务必保留此链接 http://blog.youkuaiyun.com/ani_di
Objective-C协议浅析与使用
协议(Protocol)是ObjC 2.0新增的特性。它可以简单的理解为一组方法声明,而定义交给使用者去实现,与C++或Java中的纯抽象类相似。 以ObjC强大的动态性,没有协议同样可以达到类似的效果。使用协议有以下优势:
* 显示声明要求的方法,便于交流
* 利用编译器帮助检查
* 减少不必要的容错
协议往往和委托(delegate)伴随使用。这与协议的使用场景有关:协议是一份要求其他类实现的接口,而委托是调用这些实现的途径。
程序之间的远程对象调用也需要协议,这个用的比较少。
理解了协议是纯抽象类或接口类,那么使用起来就容易多了。
@protocol MyIsOK
//method declarations
- (BOOL)isOK;
@end
协议的声明类似于class,需要一个协议名,定义一些方法(可以没有),但不能定义ivars。还可以用的一些关键字,比如@optional, @required,也是非必须的。然后就不用管了,放在头文件中给其他人使用。
如果想让类遵守协议也非常简单,在父类后面加上协议名。协议可以有多个,用逗号分开。
@interface ClassName : ItsSuperclass < protocol list >
@interface Formatter : NSObject < Formatting, Prettifying >
然后按照要求实现方法即可。如果没有实现完整或不匹配,编译器会给出警告。
调用方不知道传过来的委托有没有实现MyIsOK协议,但可以用 respondsToSelector:来动态检查(这也是前面提到,没有协议也能达到同样效果的原因,ObjC调用某个方法不需要声明)。对于协议则有更好的检查方法 conformsToProtocal:
if ( ! [receiver conformsToProtocol:@protocol(MyIsOK)] ) {
// Object does not conform to MyIsOK
}
它可以一次性检测所有接口,比respondsToSelector:要高效很多。
另一种更常见的手法是使用Type Cheking。
- (void)setDelegate:(id <MyIsOK>)delegate;
id <MyIsOK> delegate;
非正式协议(Informal Protocols)
非正式协议其实是利用类别(Category)的特性声明方法。
@interface NSObject ( MyIsOK )
- (BOOL)isOK;
@end
这里之所以用NSObject,是因为所有对象都继承于它,比较方便。由于类别并不要求一定实现,所以编译器的检查力度较弱,要求调用方自己使用 respondsToSelector 做容错处理。其实协议已经提供了@optional,就没有必要使用它了。