標籤:
Objective-C語言特性:協議(protocol),它與Java的“介面”(interface)類似。
Objective-C不支援多繼承,但可以把類的實現方法定義在協議裡面。
協議最為常見的用途是實現委託模式(Delegate pattern)。
委託模式(Delegate pattern):
用來實現對象間的通訊,
該模式的主旨是:定義一套介面,某對象若想授受另一個對象的委託,則需遵從此介面,以便成為其“委派物件”(delegate)。而這“另一對象”則可以給其委派物件回傳一些訊息,也可以在發生相關事件時通知委派物件。
此模式可以將資料與商務邏輯解耦。
由資料來源(data source)與委託(delegate)對象分別處理。
資料來源:資料來源流向類(輸入),
委託:從類流向受委託者(輸出)。
資料來源和受委託者可以是兩個不同的對象。然而一般情況下,都用同一個對象來扮演這兩種角色。
委託協議命名:
類名+Delegate(尾碼)
有了協議後,類就可以用一個屬性來存放其委派物件了。
例:
@property(nonatomic, weak) id<類名+Delgate> delegate;
// 此處用weak表示“百擁有關係”(nonowning relationship)。
// 還可以用unsafe_unretained。
// weak與unsafe_unretained的區別:如果需要在相關對象銷毀時自動清空(autoniling,參見第6條),則用weak。反之用unsafe_unretained。
@optional關鍵字(可選的):
在委派物件上調用可選方法時必須提前使用類型資訊查詢方法(參見第14條)來判斷這個委派物件能否響應相關選擇子。
例:if([_delegate respondsToSelector:@selector(委託方法)]) {
[_delegate 委託方法];
}
如果非可選方法,則不需要。
關於選擇子判斷的最佳化:
有時除了第一次檢測的結果有用之外,後續的檢測可能是多餘的。對於頻繁的檢測,也消耗效能。
對此可以最佳化:把委派物件能否響應某個協議方法這一資訊緩衝起來。
位段:
將方法響應能力緩衝起來的最佳人途徑是使用“位段”(bitfield)資料類型。這是一項無人問津的C語言特性。
把結構體中某個欄位所佔用的二進位位個數設為特定的值。
例:struct data {
unsigned int fieldA: 8; // 表示0~255之間的值
unsigned int fieldB: 4;
unsigned int fieldB: 1; // 表示0或1
}
這樣就可以嵌入一個含有位段的結構體作為執行個體變數,而結構體中的每個位段表示delegate對象是否實現了協議中的相關方法。(類似字典)
例:struct {
unsigned int didReceiveData: 1;
unsigned int didFailWithError: 1;
unsigned int didUpdateProgressTo: 1;
} _delegateFlags;
-(void)setDelegate:(id<協議> delegate){
_delegate = delegate;
_delegate.didReceiveData = [@delegate respondsToSelector:@selector(方法)]; // 值為:0或1
// ……
}
if(_delegate.didReceiveData) {
[_delegate 方法]
}
delegate對象可以有多個,所以在定義或調用時,應該把發起委託的類或執行個體加入進去。
例:- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if(tableView == tableViewA){
}else if(tableView == tableViewA){
}
}
第23條:通過委託與資料來源協議進行對象間通訊