使用SDWebImage时,表视图滚动卡顿

7

我正在cellForRowAtIndexPath中的表格视图中从互联网加载一些图片。以下是我的代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *MyIdentifier = @"ArticleCell";
    ArticleCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
    Article *article = [parser items][indexPath.row];

    cell.title.text = article.title;
    cell.newsDescription.text = article.description;
    [cell.image setImageWithURL:[NSURL URLWithString:article.image]];

    return cell;
}

我的问题是即使我使用了SDWebImage,当我向下滚动时,我的应用程序仍然会出现延迟。以下是来自Instruments的一些截图:

enter image description here

enter image description here


图片有多大? - Wain
大约在 50,000 到 200,000 之间,我们可以说是 150 KB。 - Adrian
这些图片是什么类型的?TIFF吗? - Wain
你解决了这个问题吗? - Nikita
@Nikita:我的问题是在主线程上下载完图片后还要对其进行更多的处理(使图片变成圆形),那么被接受的答案对你有用吗? - Adrian
@vBx,我已经意识到这是由于非常大的图像引起的。谢谢。 - Nikita
5个回答

5

看起来即使图像的下载是在后台线程中执行的,但图像数据的处理仍然在主线程中完成,因此会阻塞您的应用程序。您可以尝试使用SDWebImage提供的异步图像下载器。

[SDWebImageDownloader.sharedDownloader downloadImageWithURL:imageURL
                                                    options:0
                                                   progress:^(NSUInteger receivedSize, long long expectedSize)
                                                   {
                                                       // progression tracking code
                                                   }
                                                   completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished)
                                                   {
                                                       if (image && finished)
                                                       {
                                                           // do something with image
                                                       }
                                                   }
];

在您的方法中,它应该像这样:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *MyIdentifier = @"ArticleCell";
    ArticleCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
    Article *article = [parser items][indexPath.row];

    cell.title.text = article.title;
    cell.tag = indexPath.row;
    cell.newsDescription.text = article.description;
    [SDWebImageDownloader.sharedDownloader downloadImageWithURL:imageURL
                                                        options:0
                                                       progress:nil
                                                      completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished)
     {
         if (cell.tag == indexPath.row && image && finished)
         {
            dispatch_async(dispatch_get_main_queue(), ^(){
               cell.image = image;
            });

         }
     }];

    return cell;
}

  1. 它没有跟踪ImageView,因此在滚动时未将图像放置在正确的ImageView上。
  2. 图像在滚动时会消失,一段时间后再次显示出来。 似乎没有使用缓存。
- Developer
关于第二点,SDWebImageDownloader 默认会缓存图片。 - The dude
1
是的,但即使它们来自缓存,图像也不应该被错误地放置!请自行检查您的代码!2)问题仍然存在! - Developer

1
在单独的线程中下载图像,如下所示:

NSURLRequest *request = [NSURLRequest requestWithURL:yourURL];
                        [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
                            if ( data )
                            {
                                UIImage *image = [[UIImage alloc] initWithData:data];
                                [cell.image setImage:image];
                            }
                        }];

@vBx 说他已经在使用 sdWebImage 扩展,该扩展会使用一个独立的线程。 - ThorstenC

1
这可能与网络活动关系较小,更多地与图像大小有关。调整图像大小,特别是对于非整数倍数,是昂贵的。如果您的图像明显大于要放入的视图,则需要在后台线程中调整大小并缓存它们,并从视图引用缓存副本。
为确认是否存在此问题,请手动下载所有图像并引用本地副本。如果我正确,您的UITableView仍将以相同方式滞后。

0

0

检查您的图像,检查类型和大小,更重要的是:是否有一个或多个图像因其文件格式而损坏?文件大小过大,边界不规则(太大)?

尝试使用图像编辑器打开并重新保存可疑的图像文件,以确保内部文件格式正确。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接