如何在 UITableView 中高效加载图片?

Posted

技术标签:

【中文标题】如何在 UITableView 中高效加载图片?【英文标题】:How to efficiently load images in UITableView? 【发布时间】:2014-01-03 03:10:37 【问题描述】:

我有一个UITableView,其中包含大量图像。

每个单元格将有 5 张图片,这些图片是从 Parse.com 随机加载的。

我现在的查询代码在cellForRowAtIndexPath

这会导致一些问题:

1.) 滚动表格时存在一些滞后/延迟。

2.) 现在由于某种奇怪的原因,图像没有显示在正确的位置。

3.) 每次滚动表格时,图像都会重新加载/更改。

我希望图像在此UIView 上仅“加载”一次,在正确的位置,并且滚动流畅。

处理这个问题的最佳方法是什么?

这是我如何加载图像的代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath


    // set up the cell here

    // query and display random images from parse.com
    PFQuery * query = [PFUser query];
    [query whereKey:@"category" equalTo:self.cell.label.text];
    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) 

        if (error)
        
            NSLog(@"Error: %@ %@", error, [error userInfo]);
        
        else
        
            for (int i = 0; i < objects.count; i++)
            
                self.profilePicObject = [objects objectAtIndex:i];

                int imgRandom = arc4random() % [objects count];

                self.randomProfilePicObject = [objects objectAtIndex:imgRandom];

                self.imageFile = [self.randomProfilePicObject objectForKey:@"imageFile"];
                NSURL * imageFileURL = [[NSURL alloc] initWithString:self.imageFile.url];
                NSData * imageData = [NSData dataWithContentsOfURL:imageFileURL];
                UIImage * aImage = [[UIImage alloc] initWithData:imageData];

                self.cell.profilePicOne.image = aImage;
            
    

    return self.cell;


编辑:

我正在使用 SDWebImage 并且表格现在可以平滑滚动并显示图像。

新问题:

图片加载到错误的单元格中。

我正在查询表并将标签文本与我的 Parse 表中的正确字符串匹配,并使用它来显示正确的图像。

最初,有些图像会加载到正确的单元格中,而有些则不会。

当我滚动时,图像会到处出现。

解决此问题的最佳方法是什么?

这是我设置单元格的方式:

static NSString * cellIdentifier = @"FilterSelectCell";

self.cell = (FilterSelectCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    if (self.cell == nil)
    
        NSArray * nib = [[NSBundle mainBundle] loadNibNamed:@"FilterSelectCell" owner:self options:nil];
        self.cell = [nib objectAtIndex:0];

        self.cell.profilePicOne.clipsToBounds = YES;
        self.cell.profilePicOne.layer.cornerRadius = 20.0;

        self.cell.profilePicTwo.clipsToBounds = YES;
        self.cell.profilePicTwo.layer.cornerRadius = 20.0;

        self.cell.profilePicThree.clipsToBounds = YES;
        self.cell.profilePicThree.layer.cornerRadius = 20.0;

        self.cell.profilePicFour.clipsToBounds = YES;
        self.cell.profilePicFour.layer.cornerRadius = 20.0;

        self.cell.profilePicFive.clipsToBounds = YES;
        self.cell.profilePicFive.layer.cornerRadius = 20.0;
    

    self.cell.label.text = [self.myArray objectAtIndex:indexPath.row];

【问题讨论】:

您可以预加载一些随机图像,但您认为在 -viewDidLoad 中会需要许多图像。为什么要推迟到他们需要的时候?此外,您可以(并且几乎必须)使用 NSURLConnection 或 SDWebImage 之类的东西在后台下载图像。 【参考方案1】:

最好的解决方案是使用图像缓存系统(例如 SDWebImage)来防止对同一图像进行重复的 Web 查询。它非常易于使用,并允许您在从 URL 下载图像数据时使用占位符加载图像。它还异步加载图像,因此您的 UI 不会被阻塞,并且会在您的应用程序过载之前从缓存中释放图像。您只需像这样加载图像,SDWebImage 就会发挥作用:

[self.cell.profilePicOne setImageWithURL:imageFileURL placeholderImage:[UIImage imageNamed:@"LOADING_IMAGE.png"]];

SDWebImage Repository

【讨论】:

出现此错误:由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:'-[UIImageView setImageWithURL:placeholderImage:]:无法识别的选择器已发送到实例 您是否导入了我链接到您的项目中的 SDWebImage 框架?底部的链接中有安装说明。如果是这样,请将此行添加到您尝试使用它的文件的顶部:#import "SDWebImage/UIImageView+WebCache.h" 是的。当我添加 -ObjC 时,它会导致更多问题。 这有帮助吗? ***.com/questions/12306161/… 好的。我让它工作了。新问题。图像到处都是。我正在检查 Parse 中的字符串是否与单元格上的标签文本匹配,如果是,则显示正确的图像。但是当我滚动时,图像加载到错误的单元格中。【参考方案2】:

延迟加载是更好的解决方案,请查看以下讨论 Lazy loading UITableView with multiple images in each cell

【讨论】:

【参考方案3】:

使用带有 UIImageView 类别的缓存支持的异步图像下载器。我已经使用了很长时间。该死的肯定你的问题可以通过这个SDWebImage 解决

【讨论】:

【参考方案4】:

您可以查看此实用程序APSmartStorage。 支持下载、内存和磁盘缓存。

【讨论】:

以上是关于如何在 UITableView 中高效加载图片?的主要内容,如果未能解决你的问题,请参考以下文章

UITableView 中多张图片的延迟加载

UITableView 本地图片的快速加载

Swift 在 UITableView 中异步加载图像 - 顶部单元格没有图片

UITableView - 延迟加载联系人图片

iOS如何固定UITableView中cell.imageView.image的图片大小

在 UITableView 内的 UIImageView 中从 Web 加载图像