如何设置iOS缓存和磁盘存储大小?应用程序终止后,如何从磁盘存储恢复缓存?

10
我已经询问过了何时确切地从urlcache的内存和磁盘中删除内容? 现在我有一些跟进的问题:
  1. 内存缓存受iPhone的RAM限制(通常为2Gb)。但是,磁盘持久性受到64Gb或128Gb的限制。这正确吗?

  2. 是否有意义将持久性设置为超过您的内存存储量。如果您不想具有高内存占用率(并且不希望应用程序从其挂起状态中终止),它是否有用,即允许从磁盘存储还原缓存,然后返回持久化结果?

在控制点击 URLCache.shared 后,我看到以下注释:
  • 内存容量:4兆字节(4 * 1024 * 1024 字节)
  • 磁盘容量:20兆字节(20 * 1024 * 1024 字节)
  • 磁盘路径:(用户主目录)/Library/Caches/(应用程序包标识符)

没有特殊缓存要求或限制的用户应该会发现默认共享缓存实例可接受。如果此默认共享缓存实例不可接受,可以调用+setSharedURLCache:来设置不同的NSURLCache实例以从此方法返回。调用者应确保在没有其他调用者引用先前设置的共享URL缓存时调用setter。这是为了防止缓存数据的存储变得意外地无法检索。

docs

响应大小足够小,可以合理地放入缓存中(例如,如果您提供了磁盘缓存,则响应[data]的大小必须不大于磁盘缓存大小的约5%)。

我自己添加了"data"

所以我认为我的理解是正确的。


整个缓存读取/写入/恢复的过程是如何工作的?
3. 当我第一次进行网络请求时,整个响应/错误/数据是否都会被写入/存储在缓存中,然后再写入持久存储?
4. 下一次如果我想要读取,则首先从缓存开始,如果响应未过期,则返回它。磁盘存储不会改变。
如果已过期,则会发出新的请求,并且仅在获得成功响应后,才会将响应从内存和磁盘中清除,并将新响应写入缓存和磁盘。如果新请求失败,则不会清除,而是保留旧的过期数据,因此如果我们想要(加载过期响应),则会从那里加载吗?
5. 当应用程序终止时,内存会被清空。磁盘存储保持不变,除非设备内存不足或达到大小限制。在下次启动应用程序时,内存会重新加载磁盘存储中的所有内容到缓存中。
这个缓存恢复将开始加载它存储的最新数据,然后移动到旧数据,直到它达到其大小限制或仅到达磁盘上存储的项目结尾。对吗?
6. 如果在正常情况下,用户在典型的1小时会话中进行的网络操作量约为30mb,那么我应该将缓存大小设置为20mb和30mb的磁盘存储?如果有图像怎么办?我听说图像以不同的方式存储,即1mb的图像可能需要10mb的大小。那我该如何处理?
我提出这些问题是因为我想改善应用程序中的缓存体验,并提高我的整体理解,以便不会增加应用程序的内存使用量太多,这样它就不会因为我的应用程序高内存使用率或其他应用程序需要而从其挂起状态中刷新出内存。{{*记忆使用量}}

*:我们的一些网络请求将下载缩略图,因此当我增加缓存大小限制时,需要考虑周全。


1
在赏金描述中进行编辑:最后,如果URLCache提供了如此简单的缓存服务(针对图像缓存),为什么还有第三方框架?它们有哪些好处? - mfaani
1个回答

5
如果您想深入了解内存管理,您应该深入研究较低级别的API。URLSession、URLCache等都是非常高级别的API。有很多关于内存框架、图像缓存、网络缓存等方面的WWDC会议可供参考。每个部分都有很多解释。我建议您从观看所有WWDC视频开始,并进行热身。其中一些视频对核心概念有很好的解释,就像这个视频一样。
请查看今年WWDC的以下两个视频: 图像和图形最佳实践 iOS内存深入剖析 我们可以坐在这里讨论您的问题数周!但是为了快速回答:
1. 是的。由于RAM大小和存储大小,内存受限。设备和iOS可以根据需要稍微调整最大限制。
2. 正是如此,这是使用磁盘的主要目标之一。有一个名为Swap Memory的概念(如果您想要更深入的研究和研发)。

压缩数据暂时移动到磁盘中,以便为更近期使用的数据释放内存空间。

但是内存有它自己的帧缓存。有时候缓存反而降低了性能,而不是提高性能,因为有了的存在。

  1. 并不总是这样。默认情况下,只有成功的请求才会被缓存(如果服务器在头部没有要求客户端“不要缓存”)。但是,正如您所知,URLSession 在非常高级的 API 中具有许多配置选项,可以进行磁盘、内存等方面的缓存。请参阅 URLSession 文档。

  2. 请参阅 NSURLRequestCachePolicy 文档。this 是一个关于它的好教程。NSURLRequestCachePolicy 根据您选择的策略,它的行为不同,可以清除先前的缓存或保留它直到下一次成功。

  3. HomeDirectory 包含一些主要目录。iOS 对每个目录的处理方式都不同。iOS 只会清理 tmp 目录(磁盘缓存所在的位置)。您可以将缓存存储在其他目录中,例如 Documents,以防止 iOS 将其删除。但是,重点是“缓存”这个词本身的意义。

  4. 任何比实际需求更少甚至更多的空间都是关键的。它可能会损坏进程或浪费内存/磁盘空间。还记得链表发明的原因吗?您可以为不同的目的(例如图像和 JSON)拥有不同的缓存。但是,关于图像的重点是:

Image Memory Use

这些都是Foundation框架的核心,所有已知的第三方库都只是它们的包装器。因此,它们唯一的好处是:预定义的默认值基于成千上万的贡献者的知识和更高级别的API。 AlamofireKingfisher是它们的绝佳例子。
结论
正确的缓存大小取决于使用情况。取决于数据变量数量、图像数量、每个图像的大小、相同图像的访问频率等等。例如,如果您经常更改缓存中的图像,它实际上可能会对电池寿命产生不利影响!确定适当的缓存大小的最佳方法是进行测试。在Instruments下运行应用程序以同时测量性能和电池使用情况。不断增加缓存大小,直到您无法区分性能差异。那就是您需要的最大大小,至少在测试条件下是如此。然后减小大小,直到性能刚刚可接受,以确定最小可接受大小。正确的大小介于这两个大小之间,具体取决于您认为什么重要。

你有关于设置缓存和磁盘大小的建议吗?我应该如何确定一个好的大小? - mfaani
我在我的答案中添加了结论部分,提供了一个解决方案,帮助你得出合适的尺寸。 - Mojtaba Hosseini
我明白你的意思,但你能举个例子并将你的一般规则应用到它上面吗?dastet dard nakone - mfaani
1
我很想帮你,但不幸的是我正在进行一个繁重的项目,没有时间为你建立那个文档。这需要太多的时间和依赖性。互联网上有许多有用的教程可以帮助你完成这个任务。也许你应该开一个新的问题,附上你的测试文档,社区会帮助你的。最后,随意提及这个答案并通知我。 - Mojtaba Hosseini
如果您觉得我的回答有所帮助,请不要忘记点赞并将其标记为答案。谢谢。 - Mojtaba Hosseini
我明白了。我的问题集中在计算大小上。有一个有效内存的甜点,我正在尝试找到它。如果有任何关于如何进行计算的教程,请在此处提供链接。我会查看的。(我已经点赞了) - mfaani

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