iOS | “类族”的实际运用

作者: Lol刀妹 | 来源:发表于2018-08-16 18:27 被阅读370次

    1. 场景还原

    如图,三种cell的tableView:

    三种cell.gif

    后台返回的json数据如下:

    {
        "result": true,
        "data": {
            "list": [ {
                     "type": 0,
                     "title": "第一种cell,图片在左边",
                     "image": "number_1"
                     }, {
                     "type": 1,
                     "title": "第二种cell,图片在右边",
                     "image": "number_2"
                     }, {
                     "type": 2,
                     "title": "第三种cell,图片在中间",
                     "image": "number_3"
                     }, {
                     "type": 0,
                     "title": "老子反手就是一个呵呵哒🙄",
                     "image": "number_1"
                     }]
        },
        "msg": "ok",
        "code": 200,
        "executed": "0.0320830345"
    }
    

    类似于这种同种model,多种cell的tableView相信不少开发者在实际项目开发中都遇到过,我分享一下我的做法,谨以抛砖引玉。

    2. 文件组织

    2.1 什么是抽象基类?

    只用于继承、不用于实例化的类。

    3. 类族

    类族,就是将子类的实现细节隐藏在抽象基类中。(个人理解)

    这是抽象基类cell代码:

    + (instancetype)cellWithType:(CQClassClusterType)type {
        // 根据type创建对应的子类cell
        switch (type) {
            case CQClassClusterTypeA:
            {
                return [[CQClassClusterCellA alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CQClassClusterCellAReuseID];
            }
                break;
                
            case CQClassClusterTypeB:
            {
                return [[CQClassClusterCellB alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CQClassClusterCellBReuseID];
            }
                break;
                
            case CQClassClusterTypeC:
            {
                return [[CQClassClusterCellC alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CQClassClusterCellCReuseID];
            }
                break;
        }
    }
    

    使用:

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        CQClassClusterModel *model = self.dataArray[indexPath.row];
        CQClassClusterBaseCell *cell = [tableView dequeueReusableCellWithIdentifier:model.cellReuseID];
        if (!cell) {
            // 类族模式
            cell = [CQClassClusterBaseCell cellWithType:model.type];
        }
        [cell setModel:model];
        return cell;
    }
    

    4. demo

    https://github.com/CaiWanFeng/iOS_Storage

    demo所在位置:

    5. 欢迎讨论

    讨论来简书啊,其他地方转载的可能看不到。

    6. 参考

    相关文章

      网友评论

      • kirito_song:所以、等价于工厂模式下的一系列产品吧?
        kirito_song:@无夜之星辰 抽象工厂也得有工厂才行吧、不过产品线的确是类族、工厂类也是一系列类族。
        Lol刀妹:@kirito_song 类似于抽象工厂
      • 齐舞647:作者你好,底下的目录是怎么添加的。感觉很厉害
        Lol刀妹:@MrLiuQ 这我倒不清楚,估计是看我经常写简书,就给我弄个连载:joy:
        齐舞647:@无夜之星辰 只有程序员优秀作者才可以有吗?厉害厉害
        Lol刀妹:简书给的连载权限:sweat_smile:
      • 大大盆子:对类族的理解刚好与你相反,类族是将抽象基类的实现细节隐藏在子类中,调用者只需关心抽象基类的api,而实现则是放在被继承的子类中
        Lol刀妹:@大大盆子 我的那句描述“类族,就是将子类的实现细节隐藏在抽象基类中” 可以改成 “类族,就是将子类的初始化过程隐藏在抽象基类中”,这样应该就没有歧义了。
        大大盆子:@无夜之星辰 按照你demo是这个意思,不过你对类族的描述不是这个意思哦,你自己去看看
        Lol刀妹:没有相反吧。。。让我来解读一下你的这几句话:
        “类族是将抽象基类的实现细节隐藏在子类中”这句话跟我demo里的子类cell重写基类cell的setModel方法表现一致;
        “调用者只需关心抽象基类的api”跟我demo里的基类cell的cellWithType一致;
        “而实现则是放在被继承的子类中”这句话还是在子类cell重写基类cell的setModel方法中体现。
        如果你的理解真的与我相反,那肯定是你的理解出了问题,不信你可以去看下《Effective Objective-C 2.0》的第9条。
      • 镜中之宇:我觉得一个cell就行了,根据类型改变布局
        Lol刀妹:@镜中之宇 一个cell可以的,我这里只是用了一个简单demo来阐述类族。如果cell种类比较多,并且样式差别大,在一个cell里面改变布局就不太优雅了。
      • PGOne爱吃饺子:没看到有哪些优点啊,和之前写法有什么优势么
        PGOne爱吃饺子:@无夜之星辰 棒棒 👍
        Lol刀妹:Controller里创建cell的代码少了。关键是要体会这种在抽象基类里创建不同子类的思路。
      • 请叫我小白同学::yum:反手过来就是个赞
        Lol刀妹:我顺手就接住
      • Mikebanana:快师傅的文章总是那么实用
      • 老刘了:我反手过来就是一个赞
        老刘了:.......................................
        都不是一个跨区
        Lol刀妹:@MrOneAddFive 带我打卢克
      • 37e4dd6ddc60:我反手过来就是一个赞
        Lol刀妹:@梦战 可以,很强

      本文标题:iOS | “类族”的实际运用

      本文链接:https://www.haomeiwen.com/subject/bgywbftx.html