protocol:協定,就是定義聲明了一組方法,讓其他類去實作。當然,想要實作這些類,就必須要遵守這個協定。協定沒有父類,也沒有執行個體變量
協定是一種特殊的程式設計結構,專門用來聲明别的類實作的方法。它有一下常用場景:
1、需要由别的類實作的方法。
2、聲明未知類的接口。
3、兩個類之間的通信。
協定會有這幾種常用場景,是因為它的特點:協定的方法可以被任何遵守該協定的類實作。
協定并不是一個類,他隻是定義聲明了一些其他類可以實作的方法(接口)。
文法:
@protocol ZKProtocol <NSObject>
//協定方法聲明
@end
NSObject是所有協定的基協定。 @protocol 聲明協定的關鍵字。
ZKProtocol:協定名稱。
類遵守協定,那麼這個類在預設情況下就擁有了協定的所有方法。
協定方法分為兩種:@optional:可選實作方法 @required:必須實作的方法
@protocol ZKProtocol <NSObject>
@optional
//可選實作方法
- (void)doSomeThings;
@required
//必須實作的方法
- (void)printWords;
@end
當我們把協定寫好以後,那麼久需要一個類來遵守協定,實作協定方法。
.h檔案中遵守協定:
#import "ZKProtocol.h"
@interface ZKTest : NSObject<ZKProtocol>
- (void)showPrint;
@end
<ZKProtocol>:遵守協定的标志。
.m檔案中實作協定方法:
#import "ZKTest.h"
@implementation ZKTest
//ZKTest類自己的方法
- (void)showPrint{
NSLog(@"test類的方法列印");
}
#pragma ZKProtocal協定的可實作方法
- (void)doSomeThings{
NSLog(@"do someThings");
}
#pragma ZKProtocal協定必須實作方法
- (void)printWords{
NSLog(@"Hello Words!!");
}
@end
在main檔案中調用:
#import <Foundation/Foundation.h>
#import "ZKProtocol.h"
#import "ZKTest.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
//建立對象
ZKTest *test = [[ZKTest alloc]init];
//調用方法
[test showPrint];
//判斷協定方法是否被實作
if ([test respondsToSelector:@selector(printWords)]) {
//調用協定方法
[test printWords];
}
if ([test respondsToSelector:@selector(doSomeThings)]) {
[test doSomeThings];
}
}
return 0;
}
列印結果:
2017-03-13 16:02:59.148 OCdemo[1795:184583] test類的方法列印
2017-03-13 16:02:59.149 OCdemo[1795:184583] Hello Words!!
2017-03-13 16:02:59.149 OCdemo[1795:184583] do someThings
Program ended with exit code: 0
從上面的代碼來看,我們在調用協定方法的時候,是使用遵守協定的類建立的對象然後再調用方法。這就說明了這些協定方法在類遵守了協定以後,類也就擁有了這些協定方法。在使用之前要判斷協定方法是否被實作。
協定在開發中是常使用到的一種設計結構,而且常與代理(delegate)一起使用。很好的了解協定,能夠幫助我們在後面學習和使用代理。