iOS图片[翠鸟|| AlamofireImage]“由于内存问题而终止”

Posted

技术标签:

【中文标题】iOS图片[翠鸟|| AlamofireImage]“由于内存问题而终止”【英文标题】:iOS image [Kingfisher || AlamofireImage] "Terminated due to memory issue" 【发布时间】:2018-08-12 06:43:53 【问题描述】:

所以我的应用只在 CollectionView 中显示图像,并且由于内存问题而崩溃。这是内存图

这是您可以查看的示例项目。 ImageTest

我用 Kingfisher 库和 AlamofireImage 库尝试过同样的项目,但它在两者上都崩溃了。

【问题讨论】:

如果您只尝试大约 20 张图像,您是否仍然会耗尽内存?我注意到您的图像质量相对较高。我不太确定它们是否大到足以导致您耗尽内存,但我想如果您有足够的内存缓存(这就是 Kingfisher 和 AlamofireImage 所做的) 即使有 20 张图片,我也会遇到这些峰值和崩溃,尽管崩溃需要更长的时间。我没有得到的是 Kingfisher 和 AlamofireImage 没有默认缓存限制。如果是这样,我为什么会看到这样的峰值和崩溃。 只有 1 或 2 张图片会崩溃吗?另外,您可能想看看this thread for Kingfisher。 2-3 张图片不会崩溃。阅读该线程只是让我觉得我应该切换到 PINRemoteImage。我很惊讶越来越多的人在使用 AlamofireImage 或 Kingfisher 的高分辨率图像时没有遇到这个问题。 也许尝试缩小您的图像,看看是否有帮助。通常你不需要移动应用的超高分辨率图像 【参考方案1】:

问题似乎是由您的图片太大引起的。我看到了两种解决方案。

PINRemoteImage

尝试使用PINRemoteImage。它在 ObjC 中,但您可以桥接到 Swift。这个框架允许你设置缓存大小的限制,这应该可以防止你的内存被吞噬。

但是,这可能无济于事,因为您最终可能无法拥有所有图像。

缩小图像

因为,正如您所说,一张一张地缩放图像是手动的(因此很乏味),我建议在客户端缩放。

为此,您最终可能会编写自己的缓存代码。不过,我之前已经这样做过,我可以证明,获得满足您需求的东西实际上非常简单。例如,当我必须缓存图像时,我最终创建了一个字典,用于存储带有 url 键的图像。在将图像存储在字典中之前,将它们按比例缩小。

根据要求,这里有一些示例代码可以帮助您。这不是整个代码,但它是一个非常坚实的基础。

下载图片

使用Alamofire 从 URL 下载图片:

Alamofire.request(.GET, "https://robohash.org/123.png").response  (request, response, data, error) in
    self.myImageView.image = UIImage(data: data, scale:1)

缩放图像

使用来自this answer on SO 的代码。您应该缩放到您需要图像的大小,仅此而已。

存储图像

让我们稍微备份一下。我会让所有这些代码由一个类 ImageManager 或类似的东西管理。

ImageManager 应该有:

var delegate: ImageManagerDelegate?               // the delegate; more detail below
private(set) var images: [URL: UIImage] = [:]     // the cache

func getImage(from url: URL)                      // the entry point to the class; calls the delegate immediately if the image is already cached, else calls `downloadImage(url: url)`
private func downloadImage(url: URL)              // actually downloads the image; calls `cacheImage(url: url, image: downloadedImage)`
private func cacheImage(url: URL, image: UIImage) // caches the image in `images` with `url` as the key, and notifies `delegate` that an image has been cached with the specified url.

ImageManager 也应该实现ImageManagerDelegate

protocol ImageManagerDelegate 
    func imageManager(_ manager: ImageManager, didGet image: UIImage, from url: URL)

【讨论】:

您能否提供一个示例代码,说明如何简单地集成下载、缩放、缓存和显示? @AkashPopat 使用图像 I/O 框架。观看有关图像最佳做法的 WWDC 2018 视频。

以上是关于iOS图片[翠鸟|| AlamofireImage]“由于内存问题而终止”的主要内容,如果未能解决你的问题,请参考以下文章

归档时出现“没有这样的模块‘翠鸟’”错误

AlamofireImage 下载到 CoreData

将文件路径保存到 realm.io 并使用 AlamofireImage 分配图像

翠鸟图像加载错误

如何在从带有翠鸟的URL加载图像后调整UIImageView的大小

Swift 4 中的 AlamofireImage 问题