自定义UITableViewCell与大UIImageView导致滚动滞后

Und*_*ion 10 performance uitableview uiimageview uiimage

我有一个自定义的UITableViewCell,它包含一个UIImageView和一个UILabel.单元格为320x104px,imageView占据整个区域,标签位于前面.只有8个细胞.

在ViewDidLoad中我预先创建所有需要的图像,并在字典中以正确的尺寸缓存它们.

当我滚动UITableView时,每次遇到新单元格时都会有明显的延迟.这对我来说毫无意义,因为它正在使用的图像已经被创建和缓存.所有我要求的单元格都是为了让UIImageView渲染图像.

我在xib中使用自定义单元格及其视图,并将我的UITableView配置为使用它:

[self.tableView registerNib:[UINib nibWithNibName:@"ActsCell"bundle:nil] forCellReuseIdentifier:myIdentifier];

细胞创建和配置:

- (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{  
    NSString* reuseIdentifier = @"ActsCell";
    ActsCell* cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
    // Configure the cell...
    [self configureCell:cell atIndexPath:indexPath];
    return cell;
}

- (void)configureCell:(ActsCell *)cell atIndexPath:(NSIndexPath *)indexPath 
{
    Act* act = [self.acts objectAtIndex:indexPath.row];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    cell.title.text = act.name;
    cell.imageView.image = [self.imageCache objectForKey:act.uid];
}
Run Code Online (Sandbox Code Playgroud)

什么可能导致滞后?在完成所有时间密集型工作时,尝试执行任何异步操作似乎没有任何好处.

zub*_*bko 31

您是否有机会从本地文件加载图像?

通过使用Instruments我发现存在一些延迟加载机制UIImage- 实际图像数据仅在主线程上呈现它的阶段从PNG解压缩,这导致滚动期间的延迟.

因此,在加载UIImagewith -initWithContentsOfFile:方法之后,我添加了代码以将此图像的内容呈现到屏幕外的上下文,将该上下文保存为新的UIImage并将其用于UIImageViewin UITableViewCell,这使得滚动变得平滑且令人愉悦.

在参考的情况下,有一个简单的代码,我用来强制在单独的线程中读取图像内容(使用ARC):

UIImage *productImage = [[UIImage alloc] initWithContentsOfFile:path];

CGSize imageSize = productImage.size;
UIGraphicsBeginImageContext(imageSize);
[productImage drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)];
productImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Run Code Online (Sandbox Code Playgroud)

我认为UIImage以这种方式创建的表面将采用适合渲染的支持格式,这也将卸载在主线程上呈现它所需的工作.

编辑:文档UIGraphicsGetImageFromCurrentImageContext()说,它应该只用于主线程,但在网上搜索或SO显示从iOS 4开始,UIGraphics..方法变得线程安全.

  • 这对我来说绝对无价之宝.我一直在UICollectionView上乱码滚动,每个单元格中都有UIImageViews来显示照片.我尝试了很多*不同的解决方案,但我接近60FPS的唯一方法是非常hacky.我试过的大多数解决方案都涉及使用imageWithContentsOfFile预加载UIImages的NSCache,但无论我做了什么,总是有一点跳,因为新的单元格出现在屏幕上,直到我实现上面的代码.正如你所说,必须在imageWithContentsOfFile中内置某种延迟加载机制,这在文档中没有提到. (5认同)