目标C-UITableViewCell异步加载图像 [英] Objective C - UITableViewCell loading image asynchronously

查看:92
本文介绍了目标C-UITableViewCell异步加载图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在显示一张桌子.每行都有一个从URL加载的图像图标.

I am displaying a table. Each row has an image icon, loaded from an URL.

由于同步下载图像会阻塞UI,因此我已经通过大型中央调度实现了异步方式.

Since downloading images synchronously blocks the UI, I've implemented am asynchronous way via grand central dispatch.

我的问题是,当我上下滚动时,由于正在重复使用单元格,因此会显示不正确的图像.

My problem is that when I scroll down and up, since cells are being re-used, the incorrect images show up.

我可以猜测为什么会这样-这是因为重复使用的单元更新了图像,因此以前的单元现在将具有新下载的错误图像.解决此问题的理想方法是什么?

I can guess why this is happening - it's because the re-used cells update the image and therefore, previous cells will now have the newly downloaded, and wrong, image. What would be an ideal way to resolve this?

这是我的代码.

对于下载的每个图像,我将其存储在一个名为"ImageStore"的单例类中.

For each image downloaded, I'm storing it in a singleton class called "ImageStore".

// set the data for each cell - reusing the cell
- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"];

   if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
                                      reuseIdentifier:@"UITableViewCell"];
    }

    // setting the image for each cell
    // first check if there is UIImage in the ImageStore already
    NSString *imageUrl = [obj objectForKey:@"image"];
    if (imageUrl) {
      if ([[ImageStore sharedStore] imageForKey:imageUrl]) {

        [[[tableView cellForRowAtIndexPath:indexPath] imageView] setImage:[[ImageStore sharedStore] imageForKey:imageUrl]];
      } else {

        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
    dispatch_async(queue, ^{
      UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:
      [NSURL URLWithString:[obj objectForKey:@"image"]]]];
      dispatch_sync(dispatch_get_main_queue(), ^{
        [[ImageStore sharedStore]setImage:image forKey:imageUrl];
        [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]withRowAnimation:UITableViewRowAnimationNone];

            [[[tableView cellForRowAtIndexPath:indexPath] imageView] setImage:image];
      });
    });
      }
    }
    return cell;
}

推荐答案

尝试一下:

NSString *imageUrl = [obj objectForKey:@"image"];
if (imageUrl) {
  if ([[ImageStore sharedStore] imageForKey:imageUrl]) {
    [[cell imageView] setImage:[[ImageStore sharedStore] imageForKey:imageUrl]];
  } else {
  dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
  dispatch_async(queue, ^{
     UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:
     [NSURL URLWithString:[obj objectForKey:@"image"]]]];
  dispatch_sync(dispatch_get_main_queue(), ^{
     [[cell imageView] setImage:image];
     [cell setNeedsLayout];
  });
  });
}

编辑:选中 grand-central-dispatch-for-ios-lazy-loading 用于表格视图的延迟加载

EDIT : Check this grand-central-dispatch-for-ios-lazy-loading for tableview lazy loading

这篇关于目标C-UITableViewCell异步加载图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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