Objective-C 中的協(xié)議(Protocol)

特點(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];

參考資料

Working with Protocols

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容