caching - NSURLCache 在 iOS5 上提供不一致的结果,似乎是随机的

标签 caching ios5 nsurlconnection nsurlcache

我刚刚花了很长时间在 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/

相关文章:

iOS : Internet connection is available but getting time out error in web service call , 相同的网络服务在 android 中运行

objective-c - 连接到服务器

caching - RavenDB:如何防止 RAM 利用率过高?

java - 系统重启后如何处理复制缓存的重新填充

django - @cache_page() 装饰器在 django-redis-cache 中的工作

ios - 'UIViewController' 没有可见的 @interface 声明选择器

php - 缓存 MySQL 查询

iphone - iOS 5 TabBar自定义

iphone - iOS 中的自定义封面流程实现

ios - 如何从 ios 中的另一个 nib 文件访问变量