iOS開發·專職協議宣告的標頭檔案
很多第三方框架中,有這樣的一種用法:有一個.h的標頭檔案,它裡面只有協議的宣告,而且沒有對應的.m實現檔案。通常這種檔案就用來專職宣告協議的作用了。

這裡舉一個大家都能看到和下載的例子,優秀的第三方圖文混排框架: ofollow,noindex">TYAttributedLabel 。
這個框架裡面有這樣一段程式碼:
// 新增響應點選rect - (void)addRunRectDictionary:(NSDictionary *)runRectDictionary { if (runRectDictionary.count < _runRectDictionary.count) { NSMutableArray *drawStorageArray = [[_runRectDictionary allValues]mutableCopy]; // 剔除已經畫出來的 [drawStorageArray removeObjectsInArray:[runRectDictionary allValues]]; // 遍歷不會畫出來的 for (id<TYTextStorageProtocol>drawStorage in drawStorageArray) { if ([drawStorage conformsToProtocol:@protocol(TYViewStorageProtocol)]) { [(id<TYViewStorageProtocol>)drawStorage didNotDrawRun]; } } } _runRectDictionary = runRectDictionary; } 複製程式碼
1.如何判斷某物件是否服從指定協議
可以先關注這個:
if ([drawStorage conformsToProtocol:@protocol(TYViewStorageProtocol)]) 複製程式碼
這行程式碼主要做一個是否服從協議的判斷。這個協議是宣告在TYTextStorageProtocol.h檔案裡面的。大家檢視這個檔案可知,它裡面主要聲明瞭幾個協議,而且沒有對應的.m檔案。

開啟TYTextStorageProtocol.h檢視協議的程式碼:
@protocol TYViewStorageProtocol <NSObject> /** *設定所屬的view */ - (void)setOwnerView:(UIView *)ownerView; /** *不會把你繪畫出來 */ - (void)didNotDrawRun; @end 複製程式碼
2. 如何將未知型別的id物件轉換成一個服從指定協議的物件
- 接下來關注這個:
[(id<TYViewStorageProtocol>)drawStorage didNotDrawRun]; 複製程式碼
這句話裡面的 didNotDrawRun
方法是前面那個協議宣告的方法,所以,只有當前面做了判斷是否服從該協議之後,才可將暫時還是個id型別的drawStorage物件進行轉換,轉成一個服從該協議的物件,進而執行協議方法。
物件的轉換:
(id<TYViewStorageProtocol>)drawStorage 複製程式碼
3.如何使物件服從指定協議
至於一個物件是否“服從”的標準:就是該物件的類或其父類的@interface後面跟上一個協議,並實現協議的方法。
接下來再這裡的drawStorage物件,是怎樣選擇“服從” 協議 TYViewStorageProtocol
的:
- TYViewStorage.h
#import "TYDrawStorage.h" @interface TYViewStorage : TYDrawStorage<TYViewStorageProtocol> @property (nonatomic, strong)UIView *view;// 新增view @end 複製程式碼
- TYViewStorage.m
//TYViewStorageProtocol - (void)didNotDrawRun { [_view removeFromSuperview]; } 複製程式碼