我刚刚花了很长时间在 NSURLCache 上大喊大叫,所以我提供了一点建议,希望其他人可以避免我的不幸。
这一切都开始得相当合理。我的新应用项目只针对 iOS 5 及更高版本,所以我认为我可以利用新的 NSURLCache 实现来满足我所有的网络缓存需求。我需要一个 NSURLCache 的自定义子类来处理一些特殊的任务,但这一切似乎都得到了 API 的帮助。快速阅读文档,然后我开始参加比赛:
[NSURLCache setSharedURLCache:[[MyCustomCache alloc] initWithMemoryCapacity:8 * 1024 * 1024 //8mb
diskCapacity:32 * 1024 * 1024 // 32mb
diskPath:@"webcache.db"]];
我认为 8mb 的缓存可以很好地开始,我会用更大的磁盘缓存来支持它,这样我们就可以在本地提供更多更大的图像。我连接了其余的网络代码以使用 NSURLConnection(实际上,我使用了 MKNetworkKit ,但结果证明这是无关紧要的),并期望从我的缓存中获得很棒的东西。果然,所有应该被缓存的请求都尽职尽责地保存到缓存中,当响应从缓存中得到服务时,它们尽职尽责地快速返回。这是彭赞斯海盗的常规制作,在我的网络堆栈中充满了很多责任。
除了有些东西没有加起来。可以从缓存服务的请求仍然通过网络发出。除非他们不是。 缓存是否真正用于服务请求,似乎完全随机且断断续续。 我沮丧地扯掉头发,翻遍所有东西,试图弄清楚发生了什么。我构建测试应用程序,到处设置断点,撕开数据包跟踪,阅读互联网上提到 NSURLCache 的每一个字,试验缓存控制 header ,注释掉代码,绕过我的子类,甚至煞费苦心地通过跟踪NSURLCache 及其 CFNetworking friend 的程序集,试图了解其背后的神秘逻辑。我大大提高了我对 ARM 和 Objective-C 调用约定的了解,并学习了一些有关低级调试的知识,但在实际弄清楚发生了什么方面一无所获。整个事情感觉更像是 Iolanthe 的 Nightmare Song,而不是海盗王的良性独裁统治,我几乎要抛弃它了。
TL/DR 版本:NSURLCache 似乎正在工作,但随机不会返回缓存的结果,即使它有可用的结果。
最佳答案
最终,我尝试对我一直摆弄的所有位进行不同的排列。我将内存和磁盘缓存大小都设置为 8mb。
瞧,所有的怪事都消失了!应该缓存的所有内容都得到了保存。应该来自缓存的所有内容都无需网络请求即可获得服务。
iOS5 中的 NSURLCache 实现似乎还没有完成。它确实使用了磁盘和内存缓存(与 iOS4 及更早版本不同,iOS4 和更早版本只实现了内存缓存),但当请求未命中时,它实际上并没有将内存缓存传递到磁盘缓存。因此,无论给定的响应是否恰好在正确的时刻出现在内存中,基本上都是盲目的运气(好吧,受到所有其他网络和缓存使用情况的影响)。这对于减少设备上的闪存文件 IO 可能很有用,但如果您期望类的合理行为,则非常令人讨厌。
因此,随着笑声和欢快的舞蹈,我检查了我的两行修复程序并赶紧去酒吧,最终与 SO(以及 Apple 错误报告)分享这些知识,希望其他人不必经历这个又痛了。
这个悲惨故事的寓意: 如果您尝试在磁盘容量大于内存容量的 iOS5 上使用 NSURLCache,将会发生奇怪和邪恶的事情。不要这样做。并避免与魔法仙女为敌。
关于caching - NSURLCache 在 iOS5 上提供不一致的结果,似乎是随机的,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11497923/