来自 url 的 UIImage 需要很长时间才能快速加载

Posted

技术标签:

【中文标题】来自 url 的 UIImage 需要很长时间才能快速加载【英文标题】:UIImage from url takes long time to load swift 【发布时间】:2016-04-12 10:35:51 【问题描述】:

我有一个UITableView 和很多UITableViewCell,我使用此代码将内容和图像加载到UITableCell,但每个UITableViewCell 的图像显示需要很长时间。

var loadOnce : [String] = []

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell


    let cell = tableView.dequeueReusableCellWithIdentifier("ProfileActivities", forIndexPath: indexPath) as! ProfileActivitiesTableViewCell


    if !loadOnce.contains("\(indexPath.row)") 

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), 
            let LocationImage = self.postmap[indexPath.row]
            let LocationImageUrl = NSURL(string: LocationImage)
            let LocationImageData = NSData(contentsOfURL: LocationImageUrl!)

            let ProfileImage = self.postimg[indexPath.row]
            let ProfileImageUrl = NSURL(string: ProfileImage)
            let ProfileImageData = NSData(contentsOfURL: ProfileImageUrl!)

            dispatch_async(dispatch_get_main_queue(), 
                cell.locationImg.image = UIImage(data: LocationImageData!)
                cell.activitesProfileImg.image = UIImage(data: ProfileImageData!)
            );
        );
        loadOnce.append("\(indexPath.row)")

    
    return cell

将代码放在 dispatch_async 中使滚动变得窒息,但加载图像仍然需要时间。

考虑到我有很多图片,比如 Facebook 或 Instagram,如何让它更快地加载图片。

谢谢。

【问题讨论】:

您正在加载的图像的尺寸是多少?如果您只是显示缩略图,请确保下载具有小分辨率而不是高分辨率图像的图像的缩略图版本。但最后,对于图像源的缓慢互联网连接,您无能为力。如果您可以自己将它们缓存在 CDN 上,这会有所帮助。 你的代码也不会像这样工作,因为你没有在任何地方缓存你的图像。因此,当来回滚动时,由于您的 loadOnce 数组,图像不会被第二次加载,但它们也不会从您的缓存中获取(并且出队的单元格将保留以前存在的图像,这可能是错误的行)。 像 SeanLintern88 所说的那样使用 SDWebImage。这十分完美。我也在用它 @dirkgroten 为什么我需要第二次加载图像,对不起,但我是 swift 的新手,我需要知道为什么,我也尝试使用 SDWebImage 捕获 n 查看结果,顺便说一句,我只使用 1 个图像进行测试@ 987654321@ @DavidSeek 是的,我会试试看 :) 【参考方案1】:

由于异步调用和可重用性,会有问题。假设您在 IndexPath 1 的图像正在加载图像,但仍需要时间下载,同时用户向下滚动到另一个索引,即 15,并且在内部,索引 1 的相同单元格分配给索引 15,单元格 1 的图像将显示如果您没有设法处理以前对同一单元格实例的调用,请在单元格 15 中。这就是为什么最好使用一些缓存库,如SDWebImage(正如@SeanLintern88 所说)或AFNetworking's UIImageView Category

AlamoFire's UIImageView (For Swift)

如果您想这样做,最好使用子类化,它将帮助您管理调用及其终止。

在您的情况下,加载图像可能是因为您从服务器加载的实际图像的大小。 CDN 类型的服务提供了一些易于实现的技术来根据请求提供不同大小的图像。因此,即使用户上传了 1200x1200 大小的图像,但在列表屏幕上,您也可以获取其 120x120 大小的图像,这有助于加快加载速度并节省物理记忆。

【讨论】:

“单元格 1 的图像将显示在单元格 15 中”你能详细解释一下吗,我认为每一行都是索引,所以如果他滚动到索引 15,它将显示 postimg[15 ] 在单元格 15 中加载 postimg[1] 正如我所说,您正在使用相同的 LocationImageData 下载来创建 Image 并在 UIImageView 中分配它,因此如果之前的某些调用的响应迟到,那么即使您当前的数据也将填充到图像上细胞不是那个。无论下载的数据是否适用于当前的 IndexPath,您都应该设置一个检查条件。【参考方案2】:

使用以下库之一将图像异步加载到您的视图中:

1) Asyncimageview https://github.com/nicklockwood/AsyncImageView

2) SDWebImage https://github.com/rs/SDWebImage

【讨论】:

【参考方案3】:

听起来您的图像尺寸可能很大,因为代码看起来不错,通常像 FB/Insta 这样的应用会使用低分辨率再现,然后在需要时/之后以更高的分辨率加载。

大多数人使用图像获取库,例如 SDWebImage,因为这将异步获取图像并缓存它们,因此您不必将它们保存在模型上并消耗内存。

https://github.com/rs/SDWebImage

【讨论】:

以上是关于来自 url 的 UIImage 需要很长时间才能快速加载的主要内容,如果未能解决你的问题,请参考以下文章

从图像 URL 加载图像需要很长时间才能显示

MCSession 需要很长时间才能解除分配

结果集需要很长时间来处理来自 Oracle 的大数据

需要 PHP 逐行处理的 CSV 需要很长时间(或超时)才能进入 SQL 数据库

将视图插入表格 - 视图不需要很长时间才能运行 - 插入需要很长时间

数据库项目需要很长时间才能打开