iOS寫的比較多的就是UITableView,幾乎每個控制器里面都有這家伙川抡,在加上網(wǎng)絡(luò)請求,錯誤處理侍咱,loading動畫密幔,UITableViewDataSource,UITableViewDelegate昧廷,一個控制器還沒怎么寫就已經(jīng)大篇的代碼了。
當然木柬,大部分人是不會把這些都寫在控制器里然后一遍一遍的粘貼的。解決方法有很多愚战,繼承算是常用的一種齐遵,或者利用協(xié)議的特性也可以達到目的
什么是協(xié)議編程
協(xié)議的話想對更靈活,定義一個規(guī)則拓哟,別人可以遵守這個協(xié)議伶授,然后實現(xiàn)規(guī)定的方法,同時一個類可以有多個協(xié)議违诗。
但是這些協(xié)議只是相當于接口疮蹦,遵循某個協(xié)議的類只表明實現(xiàn)了這些接口,每個類都需要對這些接口有單獨的實現(xiàn)愕乎,這就很可能會導(dǎo)致重復(fù)代碼的產(chǎn)生感论。我們可以利用一些工具,為協(xié)議添加默認的實現(xiàn)比肄,比如說ProtocolKit, 或者libextobjc里面的EXTConcreteProtocol.h
芳绩。后面講大致原理
為什么要用它
下面是個人的淺顯理解,理解的錯誤的地方請輕拍:
我們使用協(xié)議的目的示括,更加靈活,從而降低耦合性鳍侣,減少冗余性(你可以實現(xiàn)吼拥,也可以不實現(xiàn))。
相比OC惑折,目前Swift里面有很多地方用到協(xié)議編程枯跑,說明它是一種比較推薦的編程方式
怎么用
本人結(jié)合作者的開發(fā)經(jīng)驗,講一講我對協(xié)議編程的理解和具體的使用粗卜,我們就拿常見的帶UITableView
控制器來舉例
我們的目的:減低重復(fù)代碼纳击,增加可擴展性
細化一下:
- 把網(wǎng)絡(luò)和網(wǎng)絡(luò)的loading,放到
RequestViewController
控制器里面 - 一個
BaseTableViewController
繼承RequestViewController
焕数,同時把UITableViewDataSource堡赔,UITableViewDelegate
方法寫到這里面 - 使用一個接口請求以及數(shù)據(jù)處理的類,里面進行具體的網(wǎng)絡(luò)請求和請求結(jié)果的處理
這樣一個控制器里面善已,就剩下一些自己特定的響應(yīng)事件雕拼、除了UITableView
的其它的UI組件,以及少部分cell代理或者數(shù)據(jù)源方法啥寇,這些也可以抽出去
下面是我從項目沖抽出來的一個Demo的代碼片段
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor whiteColor];
[self loadData];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 44;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
id obj = [self.viewModel objectAtIndexPath:indexPath];
// TODO 裝配數(shù)據(jù)--通常情況下辑甜,我們會用一個分類來進行cell注冊和取
static NSString *ID = @"ID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
}
// Configure the cell...
cell.textLabel.text = @"ticsmatic";
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
id obj = [self.viewModel objectAtIndexPath:indexPath];
// TODO 處理點擊事件
}
小Demo在這里ConcreteProtocol
補充
簡單的講一下協(xié)議的默認實現(xiàn)方式,看ProtocolKit就知道猫牡,大約也就200行代碼邓线。讓你分析一下煌恢,一句話就是為類增加方法被唄震庭。把協(xié)議的默認實現(xiàn)方法,注入到遵守這個協(xié)議的類里面二汛,必然是利用runtime拨拓。
具體代碼講解可以看這篇博文如何在 Objective-C 中實現(xiàn)協(xié)議擴展
最后
這個Demo寫的比較粗糙,僅僅是提供一種思路婿着,里面還有許多可以優(yōu)化修改的地方幸海。同時,如果我在那里寫的不好的可以批評指正