ios - uitableviewcell动态高度如何优化性能?
高洛峰
高洛峰 2017-04-17 13:28:28
0
3
728

我目前的方法是使用缓存。因为 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];

}

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

高洛峰
高洛峰

拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

全部回覆(3)
Ty80

這確實是個很常見的問題。我目前見到有兩種解決方法:
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個數可能無限多的話,這樣做是不可取的。

阿神

只支援 iOS 7 以上的,用上 tableView:estimatedHeightForRowAtIndexPath: 方法;
一般滾動時的卡頓不會是 cell 本身的複用機制的問題,有時候是重用機制沒有生效所至,有時是別的地方代碼寫得不夠符合規範。

Ty80

同學,你為什麼要快取cell,你直接快取height還可以理解,因為你快取的cell還是會被tableView重用而修改。 JeOam提到的是正確的方法,另外如果使用auto layout,要避免cell設計的過於複雜,一般來說即使你不用tableView:estimatedHeightForRowAtIndexPath:也是很流暢的。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板