search

Home  >  Q&A  >  body text

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

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

}

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

高洛峰高洛峰2773 days ago690

reply all(3)I'll reply

  • PHP中文网

    PHP中文网2017-04-17 13:30:28

    This is indeed a very common question. I currently see two solutions:
    1. Some methods will cache the frame (including the frame of each subview) instead of caching the cell. Here is an example: http://www.cnphp6.com/archives/67108
    2. If you do not need to support iOS 7 or below, you can consider using Auto Layout. There is a good answer here: http://stackoverflow.com/questions/18746929/using-auto-layout-in-uitableview-for-dynamic-cell-layouts-variable-row-heights

    If the cell reuse mechanism is completely eliminated, initializing the cell every time it is rendered will consume too much time and memory.

    After reading your code, I feel that since it has been written like this, if you want to make fewer modifications, you can consider reusing the cells of the system; if scrolling on various devices does not freeze, you can use it. Because since you have cached the cells, eliminating system reuse will not consume more memory. Of course, if the cache policy is to never release and the number of cells may be infinite, this is not advisable.

    reply
    0
  • 阿神

    阿神2017-04-17 13:30:28

    Only supports iOS 7 and above, use the tableView:estimatedHeightForRowAtIndexPath: method;
    Generally, the lag during scrolling is not a problem with the reuse mechanism of the cell itself. Sometimes it is caused by the reuse mechanism not taking effect, and sometimes it is caused by the code written in other places not meeting the specifications.

    reply
    0
  • PHP中文网

    PHP中文网2017-04-17 13:30:28

    Student, why do you cache the cells? It is understandable that you cache the height directly, because the cells you cache will still be reused and modified by the tableView. What JeOam mentioned is the correct method. In addition, if you use auto layout, you should avoid overly complex cell design. Generally speaking, even if you don't use tableView:estimatedHeightForRowAtIndexPath:, it will be very smooth.

    reply
    0
  • Cancelreply