Objective-c中的协议是一组没有实现的方法列表,任何的类均可采纳协议并具体实现这组方法。
协议类似于Java的“接口”。在Objective-C中,有两种定义协议的方式:由编译器保证的“正式协议”,以及为特定目的设定的“非正式协议”。
非正式协议为一个可以选择性实现的一系列方法列表。非正式协议虽名为协议,但实际上是挂于NSObject上的未实现分类的一种称谓,Objetive-C语言机制上并没有非正式协议这种东西,OSX 10.6版本之后由于引入@optional关键字,使得正式协议已具备同样的能力,所以非正式协议已经被废弃不再使用。
正式协议类似于Java中的"接口",它是一系列方法的列表,表明了一组功能,任何类都可以声明自身实现了某个协议。在Objective-C 2.0之前,一个类必须实现它声明符合的协议中的所有方法,否则编译器会报告错误。Objective-C 2.0版本允许标记协议中某些方法为可选的(Optional),这样编译器就不会强制实现这些可选的方法。
例如Java中的Runnable接口,其中有一个run函数,任何实现它的类都必须实现run函数。协议也类似,只是协议中的@optional之后的函数是可以选择实现的。
简单示例 :
// 定义协议, @optional后的函数为可选实现。
@protocol Visible
// 必须实现的两个函数
-(void) click ;
-(void) touch ;
// 可以选择实现
@optional
-(void) longClick ;
@end
// 类View, 实现Visible协议
@interface View : NSObject <Visible>
// 覆写init函数
-(id) init ;
// 绘制函数
-(void) draw ;
-(id) initWithWidth : (int) w andHeight:(int) h ;
@property (nonatomic) int width, height ;
@end
// ----------------- view impl -----------------------
@implementation View
// 覆写init
-(id) init
{
return [self initWithWidth:0 andHeight:0] ;
}
// 绘制view
-(void) draw
{
NSLog(@"draw in view, width = %i, height = %i.", width, height) ;
}
// 点击
-(void) click
{
NSLog(@"click the view") ;
}
// 触摸
-(void) touch
{
NSLog(@"touch the view") ;
}
// 初始化, 并且设置初始值
-(id) initWithWidth : (int) w andHeight:(int) h
{
self = [super init] ;
if ( self ) {
width = w ;
height = h ;
}
return self ;
}
@synthesize width, height ;
@end
上面定义了一个Visiable协议, 该协议中有两个必须实现的函数,即click和touch 。还有一个可以选择实现的函数longClick函数。View类实现了Visiable协议,所以必须实现click和touch函数。
使用 :
View* v = [[View alloc] init] ;
[v click] ;
协议的定义格式如下 :
协议以关键字@protocol作为区段起始,@end退出,中间为方法列表。
@protocol Visiable - (void)click; - (void)touch;
@optional
-(void) longClick ;
@end
类要实现某个协议的格式 :
@interface 类名 : 父类名 <协议名>
@end