記一次對(duì) UITableView 的探索, 使用面向協(xié)議創(chuàng)建 Cell(OC篇)

tableView是 iOS 開發(fā)中最常用的組件之一, Apple 用很好的代理模式將其解耦, 但我們開發(fā)人員卻將相應(yīng)的 Controller 變得臃腫不堪復(fù)用

就我目前的水平能想到, 盡一切力量簡化 Controller, 同時(shí)解耦的方法大約有以下幾種:

  1. 將 tableView 的 delegate, dataSource 從 Controller 中分離
  2. 將 tableViewCell 封裝, 不要將根據(jù)數(shù)據(jù)配置 cell 的操作寫著 cellForRow: 等方法中, 盡量封裝在 cell 中
    這只是我能想到的兩點(diǎn), 代碼重構(gòu)這東西, 不想數(shù)學(xué)答案, 有唯一的標(biāo)準(zhǔn)答案, 不同的程序員有不同的解耦封裝方式, 所以以上兩點(diǎn)及本片文章僅代表個(gè)人觀點(diǎn), 看官看個(gè)過場就好了, 如果您覺得我說的有道理, 那當(dāng)然歡迎討論

廢話少說了, 如果最遵循了以上兩點(diǎn), 我們會(huì)發(fā)現(xiàn), Controller 內(nèi)容少了, 因?yàn)槲覀儗?tableView的 delegate, dataSource 分離出來, 但是如果一個(gè)界面中的 cell 不盡相同, 用在 storyboard 中的表現(xiàn)形式就是, 要拖上好幾種 cell 的樣式才嫩滿足頁面的需求, 好了這個(gè)是有在 cellForRow: 中就會(huì)有大量的 if-else if -else 了, 好吧可以用 Switch 替換 , 同樣如果每個(gè)不同的 cell有不同的點(diǎn)擊事件, 那么在 didSelect方法中, 又會(huì)有大量的 if-else if -else, 這樣的代碼后期很難維護(hù), 所以針對(duì)這個(gè)問題, 我要說下自己的想法了:

面向?qū)ο笕筇卣? 封裝, 繼承, 多態(tài), 在這里我們看來要用多態(tài)了, 所有的 cell 都是 tableViewCell, 但具體的可能會(huì)有差異, 所以我們會(huì)嘗試抽象共性, 在創(chuàng)建 cell 時(shí)就可以根據(jù)多態(tài)生成不同的 cell 了

細(xì)想, 起始 不同的cell在界面上提現(xiàn)就是界面上的不同, 在數(shù)據(jù)中就是數(shù)據(jù)的不同, 可以根據(jù)數(shù)據(jù)確定 cell, 看來數(shù)據(jù)要有抽象共性, 找出抽象共性后, 我們有兩種辦法可以實(shí)現(xiàn)多態(tài), 1. 將共性放到基類中, 使用繼承的方式 2. 使用接口; 設(shè)計(jì)模式告訴我們要面向接口編程, 而不是面向?qū)崿F(xiàn)編程, 所以我在這里的基類相當(dāng)于 java 中的抽象基類, 只有接口, 沒有實(shí)現(xiàn), 在這里我們使用接口吧

  1. 首先定義接口

     #import <UIKit/UIKit.h>
    
     @protocol TableViewCellProtocol <NSObject>
     @optional
     /**
      *  注冊(cè) Cell 的 ID
      *
      *  @return 注冊(cè) Cell 的 ID
      */
     - (NSString *)registerCellIdentifier;
     
     /**
      *  對(duì)應(yīng) cell 的類, 在通過 xib, 代碼創(chuàng)建 cell 時(shí), 需要先注冊(cè), 能用到注冊(cè) Cell的 ID, 和 cell 類這兩個(gè)方法
      *
      *  @return 對(duì)應(yīng) cell 的類
      */
     - (Class)cellClass;
     
     /**
      *  點(diǎn)擊 cell 時(shí)觸發(fā)的操作
      */
     - (void)cellAction:(UITableView *)tableView;
     
     /**
      *  cell 所在的 IndexPath
      */
     - (NSIndexPath *)indexPath;
     
     @end
    
  2. 定義父 tableViewCell, 與接口建立聯(lián)系

     #import <UIKit/UIKit.h>
     #import "TableViewCellProtocol.h"
     
     @interface ParentTableViewCell : UITableViewCell
     @property (nonatomic, strong) id<TableViewCellProtocol> data;
     @end
     
     #import "ParentTableViewCell.h"
    
     @implementation ParentTableViewCell
     
     @end
    
  3. 某個(gè) cell 數(shù)據(jù)的設(shè)置

     - (NSString *)registerCellIdentifier {
         return @"AddressInfoCell";
     }
     
     - (Class)cellClass {
         return [AddressInfo class];
     }
     
     - (void)cellAction:(UITableView *)tableView {
        // TODO.. cellAction
     }       
    
  4. 某個(gè)子 Cell 設(shè)置數(shù)據(jù)

    - (void)setData:(id<TableViewCellProtocol>)data {
        [super setData:data];
        // 將 data 細(xì)化
        if (data && [data isKindOfClass:[AddressInfoModel class]]) {
            // TODO...
        }
    }
  1. dataSource, delegate 實(shí)現(xiàn)

     // 創(chuàng)建 Cell
     - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
         NSArray *subArr = self.datas[indexPath.section];
         id<TableViewCellProtocol> model = subArr[indexPath.row];
         ParentTableViewCell *cell = (ParentTableViewCell *)[tableView dequeueReusableCellWithIdentifier:[model registerCellIdentifier] forIndexPath:indexPath];
         cell.data = model;
         return cell;
     }
     
     // cell 操作
     - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
         [tableView deselectRowAtIndexPath:indexPath animated:YES];
         
         NSArray *subArr = self.datas[indexPath.section];
         id<TableViewCellProtocol> model = subArr[indexPath.row];
         if (model && [model respondsToSelector:@selector(cellAction:)]) {
             [model cellAction:tableView];
         }
     }
    

在 OC 中面向協(xié)議創(chuàng)建 Cell 這是我目前積累下來的, 如果以后有更好的方法, 會(huì)及時(shí)與大家分享, 我們的目標(biāo)是寫出可復(fù)用度高, 低耦合, 有美感的代碼, 我相信寫代碼也像做藝術(shù)一樣, 要肯想, 追求好的編碼方式

還是前面說的, 本片文章僅代表個(gè)人觀點(diǎn), 看官看個(gè)過場就好了, 如果您覺得我說的有道理, 那當(dāng)然歡迎討論, 希望能在代碼設(shè)計(jì)上更上一層樓

在 Swift 中面向協(xié)議成為一種必備的編程思想, 以后也會(huì)為大家代理關(guān)于 Swift 一些面向協(xié)議的內(nèi)容

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末撵幽,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子血柳,更是在濱河造成了極大的恐慌恰画,老刑警劉巖宾茂,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異拴还,居然都是意外死亡跨晴,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門片林,熙熙樓的掌柜王于貴愁眉苦臉地迎上來端盆,“玉大人,你說我怎么就攤上這事费封』烂睿” “怎么了?”我有些...
    開封第一講書人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵弓摘,是天一觀的道長焚鹊。 經(jīng)常有香客問我,道長韧献,這世上最難降的妖魔是什么末患? 我笑而不...
    開封第一講書人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮锤窑,結(jié)果婚禮上璧针,老公的妹妹穿的比我還像新娘。我一直安慰自己果复,他們只是感情好陈莽,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開白布渤昌。 她就那樣靜靜地躺著虽抄,像睡著了一般走搁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上迈窟,一...
    開封第一講書人閱讀 52,262評(píng)論 1 308
  • 那天私植,我揣著相機(jī)與錄音,去河邊找鬼车酣。 笑死曲稼,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的湖员。 我是一名探鬼主播贫悄,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼娘摔!你這毒婦竟也來了窄坦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤凳寺,失蹤者是張志新(化名)和其女友劉穎鸭津,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體肠缨,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡逆趋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了晒奕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闻书。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖脑慧,靈堂內(nèi)的尸體忽然破棺而出惠窄,到底是詐尸還是另有隱情,我是刑警寧澤漾橙,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布杆融,位于F島的核電站,受9級(jí)特大地震影響霜运,放射性物質(zhì)發(fā)生泄漏脾歇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一淘捡、第九天 我趴在偏房一處隱蔽的房頂上張望藕各。 院中可真熱鬧,春花似錦焦除、人聲如沸激况。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽乌逐。三九已至竭讳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間浙踢,已是汗流浹背绢慢。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留洛波,地道東北人胰舆。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像蹬挤,于是被迫代替她去往敵國和親缚窿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容