美文网首页iOS小记iOS进阶+实战iOS开发技能
iOS开发——UITableView优化之缓存cell高度

iOS开发——UITableView优化之缓存cell高度

作者: Lol刀妹 | 来源:发表于2016-11-05 15:32 被阅读2761次
    少女时代—林允儿

    为什么要缓存高度?

    因为当tableView滚动时会不停的回调- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;这个代理方法,当cell的高度需自适应内容时,就意味着每次回调这个方法时都要计算高度,而计算是要花时间了,在用户体验上的体现就是卡顿。为了避免重复且无意义的计算cell高度,缓存高度就显得尤为重要了。

    怎样缓存?

    缓存高度需要一个可变数组,每当回调- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;这个方法时,我们先去这个数组里去取,如果有,就直接拿出来,如果没有,就计算高度,并且放进数组。

    代码讲解

    • 这是我们用来装缓存高度的可变数组
    /** 缓存cell高度的数组 */
    @property (nonatomic,strong) NSMutableArray *heightArray;
    
    • 注意懒加载
     - (NSMutableArray *)heightArray{
        if (_heightArray == nil) {
            _heightArray = [NSMutableArray array];
        }
        return _heightArray;
    }
    
    • 缓存高度
     - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
        
        CGFloat height;
        
        if (self.heightArray.count > indexPath.row) {
            // 如果有缓存的高度,取出缓存高度
            height = [self.heightArray[indexPath.row] floatValue];;
        }else{
            // 无缓存高度,计算高度,并加入数组
            
            // 高度根据评论内容多少自适应
            CQGoodsCommentModel *model = self.dataArray[indexPath.row];
            // 列寬
            CGFloat contentWidth = screenWidth-20;
            // 用何種字體進行顯示
            UIFont *font = [UIFont systemFontOfSize:13];
            // 计算size
            CGSize size = [model.comment_content sizeWithFont:font constrainedToSize:CGSizeMake(contentWidth, 1000) lineBreakMode:UILineBreakModeWordWrap];
            
            // 這裏返回需要的高度
            height = size.height+60;
            // 加入数组
            [self.heightArray addObject:[NSNumber numberWithDouble:height]];
        }
        return height;
    }
    
    • 刷新tableView时记得清空高度缓存数组
    // 设置表头
        self.contentTableView.header = [CQHeader headerWithRefreshingBlock:^{
            _page = 1;
            [self.heightArray removeAllObjects];
            [self getDataIsRefresh:YES];
        }];
    

    总结

    总的来说缓存cell高度还是比较简单的,只需在原来的基础上多加一个可变数组即可,逻辑也不复杂。不过,其对性能的优化还是不容小觑的,尤其是cell内容复杂且需高度自适应内容时。强烈建议人人get这项技术,即使是入门级开发者。

    更新

    后面写了一篇更详细的:
    iOS开发 | 简单实在的cell高度自适应内容及提前计算并缓存cell高度

    相关文章

      网友评论

      • coder_feng:你确定你用double存储用float去获取值没有问题?
        Lol刀妹:不管有没有问题这种写法都是不规范的,多谢提醒:sweat_smile:
      • 请叫我小白同学::smiley: 大佬,你好,高度是固定的,也要做缓存吗?最近做新闻类的,大小内容固定的,能否指点一下!
        请叫我小白同学:@无夜之星辰 谢谢指点
        Lol刀妹:@阿阿小白啊 cell高度一样的话不用缓存
      • 宋鸿康iOS:section >1 ? 还能搞?
        Lol刀妹:这个只适用于一组的情况,大于一组用字典
      • iOS开发周立贺:就喜欢这样简单明了的干货文章,赞赞赞~
      • Zz7777777:// 返回行高
        override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {

        let viewModel = statuses![indexPath.row]
        // 1.从缓存中获取行高
        guard let height = rowHeightCaches[viewModel.status.idstr ?? "-1"] else
        {
        NJLog("计算行高")
        // 缓存中没有行高
        // 2.计算行高
        // 2.1获取当前行对应的cell
        let cell = tableView.dequeueReusableCellWithIdentifier("homeCell") as! HomeTableViewCell

        // 2.1缓存行高
        let temp = cell.calculateRowHeight(viewModel)

        rowHeightCaches[viewModel.status.idstr ?? "-1"] = temp

        // 3.返回行高
        return temp
        }

        // 缓存中有就直接返回缓存中的高度
        return height
        }

        override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // 释放缓存数据
        rowHeightCaches.removeAll()
        }
        Zz7777777:rowHeightCaches 是个字典数组 viewModel.status.idstr 是模型的唯一标识符
      • Zz7777777:我认为在模型类如果有唯一标识符 在heightForRowAtIndexPath执行的时候 如果根据字典唯一标识符取高度 如果高度没有 然后算 算出来后直接跟模型唯一标识符绑定 这样还好点
        Lol刀妹:可以,这个思路挺好的。后面我还写了篇更详细的:http://www.jianshu.com/p/af4bc69839d8
      • dengxf:看到后面居然没了。。。我竟然看完了:no_mouth:
      • ArchLL:如果是可视化布局,返回的高度是-1,系统自动为你计算高度,请问这种情况怎么缓存高度。
        Lol刀妹:@Mint丶bin 还有就是,既然都是系统计算的高度,我们都不知道高度是多少,怎么缓存?:smile:
        ArchLL:@无夜之星辰 恩恩
        Lol刀妹:@Mint丶bin 只有简单的cell我才用自动布局让系统自己计算高度,这种情况下我没缓存高度,感觉流畅度还行:sweat_smile: 复杂的cell自己计算高度然后缓存
      • 不二臣也:舔屏
        Lol刀妹:@不二臣也 一年多:grin:
        不二臣也:@无夜之星辰 撸主做开发多久了?
        Lol刀妹:@不二臣也 :sweat_smile:
      • 圣罗迦奈:好图好文 实用
        Lol刀妹:@圣罗迦奈 进来评价的人无一例外说图好,允儿果然诱人:sweat_smile:
      • YungFan:图好,文也好
        Lol刀妹:@人民重重 :joy:
        春暖花已开:@无夜之星辰 我家允儿怎么被你随随便便送人了呢:pensive:
        Lol刀妹:@YungFan 多谢兄台肯定,允儿给你了:sunglasses:
      • 陆大胖:博主,这张图,好……
        Lol刀妹:@陆大胖 不要告诉我,你是不会屈服于允儿的:joy:
        Lol刀妹:@陆大胖 好你还不点赞:smile:

      本文标题:iOS开发——UITableView优化之缓存cell高度

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