ios - 如何设置 iOS 缓存和磁盘存储大小以及如何在应用程序终止后从磁盘存储中恢复缓存?
问题描述
我已经问过究竟什么时候会从 urlcache 的内存和磁盘中删除东西?
现在我还有一些后续问题:
内存缓存受 iPhone 内存(通常为 2Gb)的限制。但是磁盘持久性受到 64Gb 或 128Gb 的限制。那是对的吗?
拥有比内存存储更多的持久性是否有意义。如果您不想占用大量内存(并且不希望应用程序从其挂起状态终止),即允许从磁盘存储中恢复缓存然后返回持久结果,它是否有用?
控制点击后,URLCache.shared
我看到以下评论:
- 内存容量:4兆字节(4 * 1024 * 1024字节)
- 磁盘容量:20兆(20*1024*1024字节)
- 磁盘路径:
(user home directory)/Library/Caches/(application bundle id)
没有特殊缓存要求或约束的用户应该发现默认的共享缓存实例是可以接受的。如果此默认共享缓存实例不可接受,
+setSharedURLCache:
则可以调用以设置NSURLCache
要从此方法返回的不同实例。调用者应注意确保在没有其他调用者引用先前设置的共享 URL 缓存时调用 setter。这是为了防止存储的缓存数据意外地不可检索。
或文档
响应大小足够小,可以合理地放入缓存中。(例如,如果您提供磁盘缓存,则响应 [data] 必须不大于磁盘缓存大小的5% 左右。)
我自己包含了数据
所以我认为我的理由是正确的。
读/写/恢复缓存的整个过程是如何工作的?
我的意思是当我第一次发出网络请求时,整个响应/错误/数据是否被写入/存储在缓存中,然后进入持久性?
下次如果我想读取,那么它首先从缓存开始,然后如果响应不是陈旧/过期的,那么它将返回它。磁盘存储不会有任何改变。
如果它已过期,那么它将发出一个新请求,并且只有在获得成功响应后,它才会从内存和磁盘中清除响应并将新响应写入缓存和磁盘。如果新请求失败,那么它不会清除,而是只会保留陈旧/过期的数据,所以如果我们想要(加载过期响应)它会从那里加载?
当应用程序终止时,内存会被刷新。除非设备内存不足或您已达到大小限制,否则磁盘存储将保持不变。下次启动应用程序时,内存会将磁盘存储中的任何内容重新加载到缓存中。
此缓存恢复将开始加载已存储的最新数据,然后移至较旧的数据,直到达到其大小限制或仅到达存储在磁盘上的项目的末尾。正确的?
- 如果在正常的一天,用户在典型的 1 小时会话中进行的网络连接量约为 30mb,那么我是否应该将缓存大小设置为 20mb 和 30mb 的磁盘存储空间?如果我有图像怎么办?我听说图像的存储方式不同,因为 1mb 的图像可能需要 10mb 的大小。那么我应该如何管理呢?
我问这一切是因为我想改善应用程序中的缓存体验并提高我的整体理解,所以我不会过多地增加应用程序的内存使用量*,因此它不会从它的内存中被冲出由于我的应用程序内存使用率高或需要其他应用程序而处于暂停状态。
*:我们的一些网络请求将下载缩略图,因此在增加缓存大小限制时需要考虑周到。
解决方案
如果您想深入了解内存管理,您应该深入了解较低级别的 API。URLSession、URLCache 等都是非常高级的 API。有很多关于内存帧、图像缓存、网络缓存等的 WWDC 会议。每个部分都有很多解释。我建议您观看所有 WWDC 视频(如果您没有观看)以进行开始和热身。一些主题对这样的核心概念有很好的解释。
看看今年 WWDC 的这两个:
我们可以坐在这里讨论您的问题数周!但为了快速回答:
- 是的。内存因内存大小而受限,而磁盘因存储大小而受限。设备和 iOS 可以根据自己的需要使用最大限制。
- 没错,这是使用磁盘的主要目标之一。有一个名为交换内存的概念(如果您愿意,可以进行更多调查和研发)
压缩数据临时移动到磁盘,以便在内存中为最近使用的数据腾出空间
但是内存在它的帧中有它自己的缓存。有时缓存会降低性能而不是提高性能。因为它是frame s。
不总是。默认情况下,只有成功请求才会缓存(如果服务器没有请求客户端在标头中“不缓存它”)。但是您可能知道,URLSession 在非常高级的 API 中具有大量用于在磁盘、内存等上进行缓存的配置。请参阅 URLSession 文档。
请参阅NSURLRequestCachePolicy文档。这是一个很好的教程。根据您选择的策略,它的行为会有所不同,可以清除以前的缓存或保留它直到下一次成功。
HomeDirectory包含一些主目录。iOS 的行为各不相同。iOS 只会清理tmp目录(磁盘缓存所在的位置)。您可以将缓存存储在其他目录(如Documents)中,以防止 iOS 将其删除。但重点是缓存词本身的含义。
实际需要的任何更少空间甚至更多空间都是至关重要的。它可能会破坏进程或浪费内存/磁盘。还记得链接列表发明的原因吗?您可以为不同的目的使用不同的缓存,例如图像和 JSON。但是关于图像的要点是:
这些都是 Foundation 框架的核心,所有已知的第三方只是它们的包装。因此,他们拥有的唯一好处是:基于数千名贡献者知识和更高级别 API 的预定义默认值。
Alamofire和Kingfisher就是很好的例子。
结论
正确的缓存大小取决于用例。取决于数据变体的数量、图像数量、每个图像的大小、同一图像的访问频率等。例如,如果您不断更改缓存中的图像,它实际上可能会对电池寿命产生不利影响!决定适当缓存大小的最佳方法是测试。在 Instruments 下运行应用程序以测量性能和电池使用情况。不断增加缓存大小,直到您无法辨别性能差异。这是您需要的最大尺寸,至少在测试条件下是这样。然后减小尺寸,直到性能勉强可以接受,以确定可接受的最小尺寸。合适的尺寸介于这两种尺寸之间,具体取决于您认为重要的尺寸。
推荐阅读
- apache-spark - 如何在 Spark 中批量处理非实时数据?
- r - 并排显示时控制表格的宽度
- powershell - 尽管安装了正确的模块,Powershell cmdlet 仍无法识别
- android - Android 'N' 级回收站视图
- reactjs - 分配给表单的对象属性显示为对象 Object 而不是实际值
- javascript - 如何在编辑不和谐消息之前添加 i++ 语句?
- reactjs - React Native - 在父视图左下角对齐文本?
- unity3d - 如何从第二个脚本访问变量数组
- kubernetes - Kong 在无 DB 模式下重新启动
- strapi - Strapi 在管理面板中缺少“文件上传”部分?