10

我有一个由 UIImageView 和 UILabel 组成的自定义 UITableViewCell。单元格为 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];
}

什么可能导致滞后?尝试做任何异步操作似乎没有任何好处,因为所有耗时的工作都已完成。

4

1 回答 1

32

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

通过使用 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();

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

编辑:文档UIGraphicsGetImageFromCurrentImageContext()说它应该只在主线程中使用,但在网络或 SO 上搜索表明从 iOS 4 开始,这些UIGraphics..方法变得线程安全。

于 2012-05-19T11:17:15.040 回答