带有大 UIImageView 的自定义 UITableViewCell 导致滚动延迟 [英] Custom UITableViewCell with large UIImageView causing scroll lag

查看:55
本文介绍了带有大 UIImageView 的自定义 UITableViewCell 导致滚动延迟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个由 UIImageView 和 UILabel 组成的自定义 UITableViewCell.单元格为 320x104px,imageView 占据了整个区域,标签在前面.只有 8 个单元格.

I have a custom UITableViewCell that consists of a UIImageView and a UILabel. The cell is 320x104px and the imageView takes up the whole area with the label in front. There are only 8 cells.

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

in ViewDidLoad I am creating all needed images up front and caching them in a dictionary at the correct dimensions.

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

When I scroll the UITableView there is a noticable lag every time a new cell is encountered. This makes no sense to me as the image it is using is already created and cached. All that I'm asking of the cell is for its UIImageView to render the image.

我正在使用一个自定义单元格,它的视图位于 xib 中,并配置我的 UITableView 以将其用于:

I am using a custom cell with its view in a xib and configuring my UITableView to use it with:

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

[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];
}

什么可能导致延迟?由于所有耗时的工作都已完成,因此尝试执行任何异步操作似乎没有任何好处.

What could be causing the lag? There would seem to be no benefit in trying to do anything Async as all the time-intensive work is done.

推荐答案

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

Do you load images from local files by any chance?

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

By using Instruments I've found that there is some lazy loading mechanism in UIImage - the real image data was decompressed from PNG only at the stage of rendering it on the main thread which caused the lag during scrolling.

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

So, after the loading of UIImage with -initWithContentsOfFile: method, I've added code to render the contents of this image to offscreen context, saved that context as new UIImage and used it for UIImageView in UITableViewCell, this made the scroll to be smooth and pleasant to the eye again.

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

In case of reference there is the simple code I'm using to force reading of image contents in separate thread (using 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 的表面将采用适合渲染的受支持格式,这也将卸载在主线程上渲染所需的工作.

And I think the surface of UIImage created in such a way will be in the supported format suited for rendering, which will also offload work needed to render it on main thread.

UIGraphicsGetImageFromCurrentImageContext() 的文档说它应该只在主线程中使用,但在网上或 SO 上搜索显示从 iOS 4 开始,UIGraphics.. 方法成为线程安全的.

The docs for UIGraphicsGetImageFromCurrentImageContext() say that it should be only used from main thread, but searching on the net or SO shows that starting from iOS 4 the UIGraphics.. methods became thread safe.

这篇关于带有大 UIImageView 的自定义 UITableViewCell 导致滚动延迟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆