特點(diǎn)
- 不同的類實(shí)現(xiàn)相似的功能
- 不同的類之間互相不干擾
聲明
可以聲明類方法、實(shí)例方法以及屬性。
例如:
@protocol XYZPieChartViewDataSource
- (NSUInteger)numberOfSegments;
- (CGFloat)sizeOfSegmentAtIndex:(NSUInteger)segmentIndex;
- (NSString *)titleForSegmentAtIndex:(NSUInteger)segmentIndex;
@end
協(xié)議可以被任意對(duì)象實(shí)現(xiàn),因此如果要聲明一個(gè)協(xié)議對(duì)象,類型應(yīng)當(dāng)設(shè)置為id,
@interface XYZPieChartView : UIView
@property (weak) id <XYZPieChartViewDataSource> dataSource;
...
@end
Objective-C 使用尖括號(hào)表示某個(gè)類實(shí)現(xiàn)了某個(gè)協(xié)議;同時(shí)作為一個(gè)類的屬性時(shí),協(xié)議對(duì)象應(yīng)當(dāng)被標(biāo)記為 weak,以防止循環(huán)引用導(dǎo)致的內(nèi)存泄露。
默認(rèn)情況下,在協(xié)議中聲明的方法是 必須實(shí)現(xiàn)的,這意味著任何聲明了協(xié)議的對(duì)象都必須實(shí)現(xiàn)協(xié)議中聲明的方法或?qū)傩浴?/p>
通過 @ required 指令,在它之后聲明的方法或?qū)傩詾?必須實(shí)現(xiàn);
協(xié)議支持 可選 的方法或?qū)傩?/h3>
通過 @optional 指令,在它之后聲明的方法或?qū)傩詾?可選;
如下表所示:
@protocol XYZPieChartViewDataSource
- (NSUInteger)numberOfSegments;
- (CGFloat)sizeOfSegmentAtIndex:(NSUInteger)segmentIndex;
@optional
- (NSString *)titleForSegmentAtIndex:(NSUInteger)segmentIndex;
- (BOOL)shouldExplodeSegmentAtIndex:(NSUInteger)segmentIndex;
@required
- (UIColor *)colorForSegmentAtIndex:(NSUInteger)segmentIndex;
@end
在代碼運(yùn)行時(shí)需要判斷 可選 的方法或函數(shù)是否被實(shí)現(xiàn)
NSString *thisSegmentTitle;
if ([self.dataSource respondsToSelector:@selector(titleForSegmentAtIndex:)]) {
thisSegmentTitle = [self.dataSource titleForSegmentAtIndex:index];
}
繼承自其他協(xié)議的協(xié)議對(duì)象
- 協(xié)議可以繼承另外一個(gè)協(xié)議
- 當(dāng)聲明一個(gè)協(xié)議時(shí),它默認(rèn)會(huì)繼承 NSObject 協(xié)議
- 實(shí)現(xiàn)某個(gè)協(xié)議的對(duì)象,需要同時(shí)實(shí)現(xiàn)這個(gè)協(xié)議和它的父協(xié)議
@protocol MyProtocol <NSObject>
...
@end
MyProtocol 協(xié)議繼承自 NSObject 協(xié)議
實(shí)現(xiàn)它的類不但需要實(shí)現(xiàn) MyProtocol 協(xié)議,也要實(shí)現(xiàn) NSObject 協(xié)議
遵照協(xié)議
一個(gè)類要遵照某個(gè)(某些)協(xié)議,寫法如下:
@interface MyClass : NSObject <MyProtocol, AnotherProtocol, YetAnotherProtocol>
...
@end
一般情況下,某個(gè)類需要實(shí)現(xiàn)的協(xié)議不會(huì)太多
如果一個(gè)類中實(shí)現(xiàn)了過多的協(xié)議,則需要考慮重構(gòu)它,把這個(gè)類拆分為多個(gè)類,分別實(shí)現(xiàn)不同的協(xié)議
同時(shí)一個(gè)協(xié)議也不宜實(shí)現(xiàn)過多的功能,實(shí)際應(yīng)用中,需要將一個(gè)大的協(xié)議盡量拆解成多個(gè)協(xié)議來實(shí)現(xiàn)多種功能
協(xié)議是匿名使用的
可以不需要知道某個(gè)實(shí)例是哪種類型,而調(diào)用協(xié)議方法
id <XYZFrameworkUtility> utility =
[frameworkObject anonymousUtility];
NSUInteger count = [utility numberOfSegments];
另一個(gè) CoreData 的例子:
NSInteger sectionNumber = ...
id <NSFetchedResultsSectionInfo> sectionInfo =
[self.fetchedResultsController.sections objectAtIndex:sectionNumber];
NSInteger numberOfRowsInSection = [sectionInfo numberOfObjects];