【问题标题】:Is there a way to clear the cache used by UIImage class?有没有办法清除 UIImage 类使用的缓存?
【发布时间】:2019-10-23 04:02:31
【问题描述】:

众所周知,UIImage 在使用imageNamed: 方法加载图像时会缓存其图像数据。

来自苹果文档: https://developer.apple.com/documentation/uikit/uiimage/1624146-imagenamed

imageNamed:

讨论:这个方法在 图像对象的系统缓存 指定的名称并返回 对象(如果存在)。如果一个匹配 图像对象尚未在 缓存,此方法加载图像 来自指定文件的数据,缓存 it,然后返回结果 对象。

因此,在使用imageNamed: 加载多个图像后,我注意到内存使用量大幅增加,并且即使在加载图像的控制器被释放后,内存仍处于使用状态。 (至少当我分配同一个控制器时它没有再次增加)

这让我想知道是否有任何方法可以在我的应用程序生命周期的任何给定时间以编程方式清除 UIImage 使用的缓存,甚至控制一些缓存参数(例如它可以使用的最大内存)

我知道我可以通过使用initWithDataimageWithDataimageWithContentsOfFile 或任何其他初始化程序而不是 imageNamed 轻松解决这个问题,但是在使用多个图像时需要这种缓存行为,比如在 @ 987654329@.

关于如何实现这一点的任何想法?

编辑: 在回答了一些问题后,我只想明确指出,需要做某事和有可能做某事之间存在巨大差距。正如我所指出的,我知道操作系统会为我处理缓存,我只是想了解 iOS SDK 施加的限制。

【问题讨论】:

  • 我知道这是一个老问题,但编辑是新的......我知道手动清除缓存的唯一方法是通过一种未记录的私有方法,所以我认为这不太可能。
  • @KevinLow 真的吗?那是什么方法?我会很高兴和它一起玩!私有 API 规则不适用于仅临时应用程序 ;)
  • 哈哈,是UIImage上的类方法。 [UIImage _flushSharedImageCache]; 还有[image removeFromCache];[UIImage removeImageNameFromCache:@"imageName"];
  • @Rajneesh071 很好的答案,但似乎UIImage 在调用imageNamed: 方法时使用的缓存是内存缓存,而不是文件磁盘缓存(因为它没有任何意义,因为来自imageNamed: 的图像已经是应用程序包中的一个文件,与使用imageWithData: 和其他类似方法加载的图像不同)。因此_flushSharedImageCache 清除了缓存中图像使用的分配内存,从而减少了重内存使用应用程序中的内存警告数量(当我问这个问题时,这最初是我的意图)。但无论如何 tks ;)

标签: objective-c ios caching uiimage


【解决方案1】:

据我所知,无法手动清除此 iOS 托管缓存。一般来说,这是一个红鲱鱼。当操作系统为您管理某些事情时,您无需担心。只要您正确释放分配/保留的任何内容并适当地处理内存警告,您就可以尽自己的一份力量。

【讨论】:

  • 需要做某事有可能做某事之间存在巨大差距。正如我在我的问题中指出的那样,我知道我不需要这样做,因为我可以使用 initWithData 创建图像,我只是想看看 SDK 施加的限制.
  • 我的意思是你不应该担心操作系统管理的缓存正在使用的内存。担心您的应用程序的内存需求并管理您自己存储或缓存的任何内容是公平的。操作系统将根据需要管理它的缓存,除非 Apple 提供文件和建议,否则该实现对您来说是不透明的。您当然可以使用 initWithData 并实现自己的图像缓存(或不实现)。很难想象哪种情况会更好。
  • 抛开原因,如果你想 100% 控制图像缓存,我会实现你自己的缓存,永远不要使用 imageNamed:
  • 抱歉轰炸你,想再补充一点。我在您的问题中回答了我做 b/c 的方式,您表示 iOS 的图像缓存行为是您需要解决的“问题”。这不是问题,操作系统为此缓存分配的任何内存都是操作系统的责任,而不是您需要担心的问题。如果您遇到应用程序需要太多内存才能运行的问题,则该问题不在图像缓存中。您可以假设操作系统会在内存不足的情况下适当地刷新此缓存。
  • @XJones 如果您的应用程序由于内存问题而崩溃 - 用户不会责怪操作系统,他们会谴责您的应用程序!因此,您可能正在尽自己的一份力量 - 但用户对此一无所知。
【解决方案2】:

答案取自Kevin Low评论


如果您可以使用 私有 API(例如,在仅 AdHoc 的应用程序中),请使用此 UIImage method 从缓存中删除所有图像

[UIImage _flushSharedImageCache];

【讨论】:

  • UIImage 没有这种方法。
  • @Curnelious 感谢您的反馈,我删除了真正不存在的那些,并添加了指向私有 UIImage 头文件的链接,指向我在答案中留下的那个。
【解决方案3】:

缓存将在需要时清空,即当应用程序收到内存不足警告时。您没有理由自己这样做,也没有可用的公共 API。

【讨论】:

  • 我不会争论原因,正如我在其他答案的评论中已经解释的那样。但是,您知道它是如何完成的,即使使用私有 API 也是如此? (因为我的应用是临时分发的,所以不用担心被苹果商店拒绝)
  • 有一个很好的理由:我的应用程序的内存使用量不够高,无法触发内存警告,但仍然很高。旋转后,分配了更多内存,并且应用程序由于“内存错误”而被终止,而没有内存警告。如果我可以在轮换之前释放缓存内存,应用程序将很好地在轮换中幸存下来……没有公共 API == 没有选项。
【解决方案4】:

也许我们有不止一种删除缓存图像的方法,但我认为您可以使用 self.cache.removeAllObjects() 如果您使用 Cache() 对象,这是更多方法之一。如果我错了,每个人都可以纠正我

【讨论】:

    猜你喜欢
    • 2016-04-19
    • 1970-01-01
    • 2022-01-19
    • 2021-11-17
    • 2015-07-01
    • 2012-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多