在自定义 uitableviewcell 中设置图像会导致延迟
Posted
技术标签:
【中文标题】在自定义 uitableviewcell 中设置图像会导致延迟【英文标题】:Setting image in custom uitableviewcell causes lag 【发布时间】:2014-06-29 03:20:34 【问题描述】:我有一个使用自定义单元格的 uitableview。但是,当我滚动表格视图时,会有一些严重的滞后。当我用图像设置 UIImaveView 的图像属性时会发生这种情况。我正在从目录访问图像。但由于文件 IO 很慢,我使用 dispatch_async 将图像加载到单独线程上的 UIImage 对象中。
但仍有一些滞后。当我在没有任何图像的情况下上下滚动行时,滚动非常流畅。但是,当该行实际上有图像时,就会出现滞后。动量滚动将停止,然后应用程序变得无响应,然后当图像最终加载时,动量会从中断处继续。
我不确定是什么导致了延迟。起初我认为这与图像太大有关,所以我尝试将其缩小。仍然滞后。同样,如果我不在自定义单元格中设置图像,则没有延迟。但是当我设置它时会有滞后。我不知道如何解决这个问题。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
DHTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kReuseIdentifierGoalCell forIndexPath:indexPath];
[self configureCell:cell forIndexPath:indexPath isForOffscreenUse:NO];
return cell;
- (void)configureCell:(DHTableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath isForOffscreenUse:(BOOL)offscreenUse
if (cell == nil)
return;
[cell setDelegate:self];
PATH_TO_FILE = SQLITE_QUERY_TO_GET_PATH; //some pseudo codes
__weak typeof(sSelf)wSelf = sSelf;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
__strong typeof(wSelf)sSelf = wSelf;
UIImage *unscaled_image = [UIImage imageWithContentsOfFile:PATH_TO_FILE];
UIImage *image = [unscaled_image imageScaledToFitInSize:kCellUIImageSize];
__weak typeof(sSelf)wSelf = sSelf;
dispatch_async(dispatch_get_main_queue(), ^
__strong typeof(wSelf)sSelf = wSelf;
DHTableViewCell *cell = (id)[sSelf.tableView cellForRowAtIndexPath:indexPath];
if (cell)
[cell.imageStored setImage:image]; //Commenting this out relieves all lag
);
);
【问题讨论】:
你从哪里调用这个代码片段?每个单元格是否有不同的图像? 在tableview中调用:cellforindexpath: 每个单元格都有不同的图像。 我不知道这种方法。你能发布整个方法。它与cellForRowAtIndexpath
有什么关系?我注意到你在这段代码中回调cellForRowAtIndexPath
,这看起来很奇怪。通常你会在cellForRowAtIndexPath
调用的后台线程中加载图像 - 然后你已经有了对单元格的引用
好的,我更新了代码以使其更易于理解。我使用cellForRowAtIndexPath 来获取对单元格的引用的原因是,当图像最终加载时,单元格有可能最终离开屏幕。表格视图的工作方式是回收单元格,因此如果我只使用方法中单元格的引用,它可能最终会更新错误的单元格。 (如果我误解了这是如何工作的,请纠正我)
【参考方案1】:
@Calimari328 我讨厌将其作为答案,因为它并不能真正回答您的问题,但事实是您真正应该做的是使用库来实现这一目标。例如SDWebImage
例子:
#import <SDWebImage/UIImageView+WebCache.h>
...
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *MyIdentifier = @"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier] autorelease];
// Here we use the new provided setImageWithURL: method to load the web image
[cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
cell.textLabel.text = @"My Text";
return cell;
您必须重新考虑这一点,单元格会被重复使用,这意味着每次滚动应用时都会尝试再次下载图像。性能如何?记忆 ?缓存?加工?
当您仔细考虑它时,它比简单的异步任务要复杂得多。幸运的是,有一些开源项目可以实现这一目标。无需重新发明***。
请注意,如果您想编写自己的代码,我并不是在宣传任何库,您也可以这样做。也可以search on the web 方便实现。
【讨论】:
这是一个很棒的开源库,但我的项目没有从 Internet 加载它。它正在从磁盘加载它。 再一次,我只能建议您在阅读了An asynchronous memory + disk image caching with automatic cache expiration handling
的描述后尝试一下以上是关于在自定义 uitableviewcell 中设置图像会导致延迟的主要内容,如果未能解决你的问题,请参考以下文章
在 Storyboard 中设计的自定义 UITableViewCell 中的自定义 UIView
UIImageView 未在自定义 UITableViewCell 中显示图像
UITableViewCell 内的 UIScrollView - 水平滚动