uitableviewcell动态高度如何优化性能?

发布于 2022-08-31 09:23:47 字数 1560 浏览 10 评论 0

我目前的方法是使用缓存。因为 heightForRowAtIndexPath 先于 cellForRowAtIndexPath 调用。那么在 heightForRowAtIndexPath 的时候初始化 cell,缓存起来。
cellForRowAtIndexPath 的时候,从缓存读取。

现在问题来了。。。。。

因为cell自身的复用机制所致,滚动的时候,出现一些问题。
如果彻底干掉cell自身飞复用机制,那么每次渲染初始化cell,太耗时间和内存了。

怎么都不行,如何是好?

我的代码如下:

objc//计算cell的高度,这里初始化cell了。那么缓存起来。

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    FeedCell *cell = [self getCellFromIndexPath:indexPath];
    return cell.frame.size.height;
}



//把Cell复用逻辑写在一个方法里
- (FeedCell*)getCellFromIndexPath:(NSIndexPath*)indexPath
{
    Post *post = [self.dataSource objectAtIndex:indexPath.row];
    NSString *key = [NSString stringWithFormat:@"%@%d_%d%d", CellIdentifier, post.pid, indexPath.row, indexPath.section];
    FeedCell *cell = [self.cellCache objectForKey:key];//看看是否有cell的缓存。
    if (!cell) {

        //系统自身的复用机制。
        cell = [self.feedTableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (!cell)
        {
            cell = [[FeedCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        }


        [cell setAutoFrame];

        cell.tag = post.pid;
        [self.cellCache setObject:cell forKey:key];
    }

    return cell;
}




//因为计算cell高度的时候已经初始化了。那么这里从缓存读取。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

    return [self getCellFromIndexPath:indexPath];

}

编辑器对大片代码没法高亮,我反复折腾很久,代码排版不尽人意。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦魇绽荼蘼 2022-09-07 09:23:47

这确实是个很常见的问题。我目前见到有两种解决方法:
1. 有些方法会缓存frame(包括各个子view的frame)而不是缓存cell。这里有一篇例子:http://www.cnphp6.com/archives/67108
2. 如果不需支持iOS 7以下的话,可以考虑用Auto Layout。这里有一篇很好的答案:http://stackoverflow.com/questions/18746929/using-auto-layout-in-uitableview-for-dynamic-cell-layouts-variable-row-heights

如果彻底干掉cell自身复用机制,那么每次渲染初始化cell,太耗时间和内存了。

看了下你的代码,觉得既然已经写成这样了,想少修改点,可以考虑把系统的cell复用干掉;如果在各个设备上滚动不卡顿,就可以采用。因为既然你已经把cell缓存起来了,干掉系统的复用并不会更耗内存。当然如果缓存策略是从不释放,而cell个数可能无限多的话,这样做是不可取的。

羁〃客ぐ 2022-09-07 09:23:47

只支持 iOS 7 以上的,用上 tableView:estimatedHeightForRowAtIndexPath: 方法;
一般滚动时的卡顿不会是 cell 自身的复用机制的问题,有时候是重用机制没有生效所至,有时候是别的地方代码写得不够符合规范。

妄司 2022-09-07 09:23:47

同学,你为什么要缓存cell,你直接缓存height还可以理解,因为你缓存的cell还是会被tableView重用而修改。JeOam提到的是正确的方法,另外如果使用auto layout,要避免cell设计的过于复杂,一般来说即使你不用tableView:estimatedHeightForRowAtIndexPath:也是很流畅的。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文