Performance 带有大UIImageView的自定义UITableViewCell导致滚动延迟

Performance 带有大UIImageView的自定义UITableViewCell导致滚动延迟,performance,uitableview,uiimageview,uiimage,Performance,Uitableview,Uiimageview,Uiimage,我有一个自定义UITableViewCell,它由UIImageView和UILabel组成。该单元为320x104px,imageView占据整个区域,标签在前面。只有8个细胞 在ViewDidLoad中,我提前创建了所有需要的图像,并将它们以正确的维度缓存在字典中 当我滚动UITableView时,每次遇到新单元格时都会出现明显的延迟。这对我来说毫无意义,因为它使用的图像已经创建并缓存。我只要求单元格的UIImageView渲染图像 我正在使用自定义单元格及其在xib中的视图,并将UITab

我有一个自定义UITableViewCell,它由UIImageView和UILabel组成。该单元为320x104px,imageView占据整个区域,标签在前面。只有8个细胞

在ViewDidLoad中,我提前创建了所有需要的图像,并将它们以正确的维度缓存在字典中

当我滚动UITableView时,每次遇到新单元格时都会出现明显的延迟。这对我来说毫无意义,因为它使用的图像已经创建并缓存。我只要求单元格的UIImageView渲染图像

我正在使用自定义单元格及其在xib中的视图,并将UITableView配置为与以下内容一起使用:

[self.tableView注册表项nb:[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];
}

是什么导致了这种滞后?由于所有时间密集型工作都已完成,因此尝试异步执行任何操作似乎没有任何好处

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

通过使用工具,我发现在
UIImage
中有一些延迟加载机制-真正的图像数据仅在主线程上呈现时才从PNG中解压缩,这导致了滚动过程中的延迟

因此,在使用
-initWithContentsOfFile:
方法加载
UIImage
后,我添加了代码,将此图像的内容呈现到屏幕外上下文,将该上下文保存为新的
UIImage
,并将其用于
UITableViewCell
中的
UIImageView
,这使卷轴再次变得光滑、悦目

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

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


编辑:UIGraphicsGetImageFromCurrentImageContext()的文档说它只能从主线程使用,但是在网络上搜索显示从iOS 4开始,
UIGraphics..
方法变得线程安全

我能想到两件事。一种是,由于没有正确设置
reusableIdentifier
,因此出列失败。另一个是图像的大小。即使图像已加载,CG也需要在显示之前处理图像数据,这可能涉及到昂贵的操作,如缩放、合成等@Lvsti您能否详细说明我没有正确设置reuseIdentifier?您是对的,可能不是这样,否则,当您退出队列时,您将无法获得任何单元格…如果您的意思是我不使用If(cell==nil){//Create cell},那么如果使用registernb:forCellReuseIdentifier:这不是必需的,因为单元格创建延迟到VC。是的,我意识到了这一点。至于图像,它们的大小是多少?这对我来说绝对是无价的。我曾经在UICollectionView上用UIImageView在每个单元格中滚动显示一张照片,这让我很痛苦。我尝试了很多不同的解决方案,但唯一接近60FPS的方法是非常困难的。我尝试的大多数解决方案都涉及使用imageWithContentsOfFile预加载UIImages的NSCache,但无论我做什么,在实现上述代码之前,屏幕上总是出现新的单元格,因此会有一点跳跃。正如你所说,一定有某种延迟加载机制内置到带有文档中未提及的文件内容的图像中。这对我来说很有效,在存储UIImage而不是下载的数据后,它会更平滑,然后每次使用时都转换为UIImage。非常感谢。我一直在寻找缓慢/起伏的原因。先生,很抱歉提出了一个旧的线程,但我有一个类似的问题,但我不知道如何/在CellForRowatineXpath中使用上述代码上述代码不适用于
CellForRowatineXpath
。任何平滑滚动包含大量数据的单元格(本例中为图像)的场景都是将加载的最重部分移动到单独的线程。此代码用于并行工作线程,它将确保图像加载在工作线程中,而不是主UI线程中。---但您应该首先了解如何在单独的线程中加载表视图单元格的图像,这是不同的主题。
UIImage *productImage = [[UIImage alloc] initWithContentsOfFile:path];

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