使用GCD异步下载UITableView的图像 [英] Asynchronous downloading of images for UITableView with GCD

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

问题描述

我正在使用GCD异步下载我的uitableview的图像,但是有一个问题 - 当滚动图像闪烁并且一直在变化时。我尝试将每个单元格的图像设置为nil,但它没有多大帮助。
快速向上滚动时,所有图像都是错误的。我该怎么办?
这是我的单元格方法:

I'm downloading images for my uitableview asynchronously using GCD, but there is a problem - when scrolling images flicker and change all the time. I tried setting image to nil with every cell, but it doesn't help much. When scrolling back up fast, all images are wrong. What can I do about that? Here is my method for cells:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    if (self.loader.parsedData[indexPath.row] != nil)
    {
        cell.imageView.image = nil;
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
            dispatch_async(queue, ^(void) {

                NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[self.loader.parsedData[indexPath.row] objectForKey:@"imageLR"]]];

                UIImage* image = [[UIImage alloc] initWithData:imageData];

                dispatch_async(dispatch_get_main_queue(), ^{
                    cell.imageView.image = image;
                    [cell setNeedsLayout];
                     });
            });

    cell.textLabel.text = [self.loader.parsedData[indexPath.row] objectForKey:@"id"];
    }
    return cell;
}


推荐答案

这里的问题是你的图像获取块保持对tableview单元格的引用。下载完成后,即使您已经回收单元格以显示不同的行,它也会设置 imageView.image 属性。

The problem here is that your image-fetching blocks are holding references to the tableview cells. When the download completes, it sets the imageView.image property, even if you have recycled the cell to display a different row.

在设置图像之前,您需要下载完成块来测试图像是否仍然与图像相关。

You'll need your download completion block to test whether the image is still relevant to the cell before setting the image.

值得注意的是你不要将图像存储在单元格以外的任何位置,因此每次在屏幕上滚动行时都会再次下载它们。你可能想在某个地方缓存它们并在开始下载之前查找本地缓存的图像。

It's also worth noting that you're not storing the images anywhere other than in the cell, so you'll be downloading them again each time you scroll a row onscreen. You probably want to cache them somewhere and look for locally cached images before starting a download.

编辑:这是一个简单的测试方法,使用单元格的 tag property:

here's a simple way to test, using the cell's tag property:

- (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    cell.tag = indexPath.row;
    NSDictionary *parsedData = self.loader.parsedData[indexPath.row];
    if (parsedData)
    {
        cell.imageView.image = nil;
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
        dispatch_async(queue, ^(void) {

            NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:parsedData[@"imageLR"]];

            UIImage* image = [[UIImage alloc] initWithData:imageData];
            if (image) {
                 dispatch_async(dispatch_get_main_queue(), ^{
                     if (cell.tag == indexPath.row) {
                         cell.imageView.image = image;
                         [cell setNeedsLayout];
                     }
                 });
             }
        });

        cell.textLabel.text = parsedData[@"id"];
    }
    return cell;
}

这篇关于使用GCD异步下载UITableView的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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