记一次对 UITableView 的探索, 使用面向协议创建 Cell(OC篇)

tableView是 iOS 开发中最常用的组件之一, Apple 用很好的代理模式将其解耦, 但我们开发人员却将相应的 Controller 变得臃肿不堪复用

就我目前的水平能想到, 尽一切力量简化 Controller, 同时解耦的方法大约有以下几种:

  1. 将 tableView 的 delegate, dataSource 从 Controller 中分离
  2. 将 tableViewCell 封装, 不要将根据数据配置 cell 的操作写着 cellForRow: 等方法中, 尽量封装在 cell 中
    这只是我能想到的两点, 代码重构这东西, 不想数学答案, 有唯一的标准答案, 不同的程序员有不同的解耦封装方式, 所以以上两点及本片文章仅代表个人观点, 看官看个过场就好了, 如果您觉得我说的有道理, 那当然欢迎讨论

废话少说了, 如果最遵循了以上两点, 我们会发现, Controller 内容少了, 因为我们将 tableView的 delegate, dataSource 分离出来, 但是如果一个界面中的 cell 不尽相同, 用在 storyboard 中的表现形式就是, 要拖上好几种 cell 的样式才嫩满足页面的需求, 好了这个是有在 cellForRow: 中就会有大量的 if-else if -else 了, 好吧可以用 Switch 替换 , 同样如果每个不同的 cell有不同的点击事件, 那么在 didSelect方法中, 又会有大量的 if-else if -else, 这样的代码后期很难维护, 所以针对这个问题, 我要说下自己的想法了:

面向对象三大特征: 封装, 继承, 多态, 在这里我们看来要用多态了, 所有的 cell 都是 tableViewCell, 但具体的可能会有差异, 所以我们会尝试抽象共性, 在创建 cell 时就可以根据多态生成不同的 cell 了

细想, 起始 不同的cell在界面上提现就是界面上的不同, 在数据中就是数据的不同, 可以根据数据确定 cell, 看来数据要有抽象共性, 找出抽象共性后, 我们有两种办法可以实现多态, 1. 将共性放到基类中, 使用继承的方式 2. 使用接口; 设计模式告诉我们要面向接口编程, 而不是面向实现编程, 所以我在这里的基类相当于 java 中的抽象基类, 只有接口, 没有实现, 在这里我们使用接口吧

  1. 首先定义接口

     #import <UIKit/UIKit.h>
    
     @protocol TableViewCellProtocol <NSObject>
     @optional
     /**
      *  注册 Cell 的 ID
      *
      *  @return 注册 Cell 的 ID
      */
     - (NSString *)registerCellIdentifier;
     
     /**
      *  对应 cell 的类, 在通过 xib, 代码创建 cell 时, 需要先注册, 能用到注册 Cell的 ID, 和 cell 类这两个方法
      *
      *  @return 对应 cell 的类
      */
     - (Class)cellClass;
     
     /**
      *  点击 cell 时触发的操作
      */
     - (void)cellAction:(UITableView *)tableView;
     
     /**
      *  cell 所在的 IndexPath
      */
     - (NSIndexPath *)indexPath;
     
     @end
    
  2. 定义父 tableViewCell, 与接口建立联系

     #import <UIKit/UIKit.h>
     #import "TableViewCellProtocol.h"
     
     @interface ParentTableViewCell : UITableViewCell
     @property (nonatomic, strong) id<TableViewCellProtocol> data;
     @end
     
     #import "ParentTableViewCell.h"
    
     @implementation ParentTableViewCell
     
     @end
    
  3. 某个 cell 数据的设置

     - (NSString *)registerCellIdentifier {
         return @"AddressInfoCell";
     }
     
     - (Class)cellClass {
         return [AddressInfo class];
     }
     
     - (void)cellAction:(UITableView *)tableView {
        // TODO.. cellAction
     }       
    
  4. 某个子 Cell 设置数据

    - (void)setData:(id<TableViewCellProtocol>)data {
        [super setData:data];
        // 将 data 细化
        if (data && [data isKindOfClass:[AddressInfoModel class]]) {
            // TODO...
        }
    }
  1. dataSource, delegate 实现

     // 创建 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 中面向协议创建 Cell 这是我目前积累下来的, 如果以后有更好的方法, 会及时与大家分享, 我们的目标是写出可复用度高, 低耦合, 有美感的代码, 我相信写代码也像做艺术一样, 要肯想, 追求好的编码方式

还是前面说的, 本片文章仅代表个人观点, 看官看个过场就好了, 如果您觉得我说的有道理, 那当然欢迎讨论, 希望能在代码设计上更上一层楼

在 Swift 中面向协议成为一种必备的编程思想, 以后也会为大家代理关于 Swift 一些面向协议的内容

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容