【问题标题】:Is NSURLCache persistent across launches?NSURLCache 在启动时是否持久?
【发布时间】:2013-08-26 19:55:03
【问题描述】:

我正在为我的 iOS 应用程序寻找一个在启动时保持不变的网络缓存解决方案。我开始阅读 NSURLCache,但没有看到任何关于持久性的提及。有谁知道当您使用 NSURLCache 然后关闭并打开应用程序时这是如何表现的?会持续吗?

【问题讨论】:

  • 更清楚一点,无论何时使用NSURLConnection,它都会根据缓存策略和响应缓存头将结果缓存在内存和磁盘上。磁盘缓存意味着跨负载的持久性,我可以亲自验证这种行为。
  • @Rob 如果没记错的话,NSURLCache 在 iOS 5 中的行为发生了变化,这也是苹果开始区分操作系统可能随时删除的文件、应该通过 iCloud 同步的文件和用于这些都不是真的。那么您的来源可能来自 5 之前的世界吗?
  • @Tommy 做了一些研究,我发现持久存储缓存很挑剔,但在 iOS 中有效。我发现如果 (a) 您使用默认的 NSURLRequest cachePolicyNSURLRequestUseProtocolCachePolicy,它不会缓存到持久存储;但是 (b) 响应不包括 Cache-Control 标头。但是,如果您使用 NSURLRequestReturnCacheDataElseLoad 中的 cachePolicy,或者如果来自服务器的响应指定了特定的 Cache-Control 标头(例如 public, max-age=1835400),它将缓存到持久存储。或者您也可以手动添加到NSURLCache
  • 您的措辞可能令人困惑。如果我错了,请纠正我:通常:缓存和持久性是正交的。 缓存是为了提高性能,根据需要可能会或可能不会持久化。 持久性只是“我如何在应用重启时持久化任何数据?”任何持久性技术都可以用作持久化“缓存”数据的后端。因为缓存数据只是数据。术语“缓存”只是传达数据的预期用例。 特别是:您在这里谈论的是通过不同的启动来持久化缓存,我认为这正确的。

标签: ios nsurlcache


【解决方案1】:

NSURLCache 根据来自服务器的缓存响应、缓存配置和请求的缓存策略自动缓存通过NSURLConnectionUIWebViews 发出的请求。这些响应在缓存的生命周期内存储在内存和磁盘上。


一边

我使用以下代码验证了该行为。 您无需在自己的代码中使用以下任何内容。这只是为了证明我是如何确认该行为的。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Prime the cache.
    [NSURLCache sharedURLCache];
    sleep(1); // Again, this is for demonstration purposes only. I wouldn't do this in a real app.

    // Choose a long cached URL.
    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://cdn.sstatic.net/stackoverflow/img/favicon.ico"]];

    // Check the cache.
    NSCachedURLResponse *cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:request];
    NSLog(cachedResponse ? @"Cached response found!" : @"No cached response found.");

    // Load the file.
    [NSURLConnection sendSynchronousRequest:request returningResponse:NULL error:NULL];

    return YES;
}

代码执行以下操作:

  1. 启动缓存。我注意到在缓存初始化并有机会扫描磁盘之前缓存不会返回缓存结果的行为。
  2. 为长缓存文件创建请求。
  3. 检查 URL 是否存在响应并显示状态。
  4. 加载 URL。

首次加载时,您应该会看到“未找到缓存响应”。在后续运行中,您将看到“找到缓存响应!”

【讨论】:

  • 感谢您的示例代码。您使用 cachedResponseForRequest 的原因是否只是为了证明响应已被缓存?每当您想访问缓存时,您是否必须使用 cachedResponseForRequest ?我认为如果你连续调用 sendSynchronousRequest,取决于在 NSURLRequest 上设置的缓存策略,它会自动为你命中缓存。不是这样吗?
  • 对不起,cachedResponseForRequest: 调用只是为了证明该值已被缓存。您不需要任何特殊的缓存处理代码来使您的缓存工作。我会相应地更新我的答案。
  • 为什么 sleep(1) 行如此重要?我有一个演示下载应用程序,在我将这种代码放入更复杂的应用程序之前,我已经构建了该应用程序的功能/证明缓存代码。如果我在[NSURLCache setSharedURLCache:sharedCache]; 之后的应用程序委托didFinishLaunchingWithOptions 方法中没有添加 sleep(1),那么整个缓存系统就会损坏。它不起作用。但是,如果我像描述的那样睡在我的应用程序委托中,那么整个系统都可以完美运行。我应该接受在我的生产应用程序中需要一个奇怪的 sleep(1) 调用,还是有另一种技术可以解决问题?
  • @JohnErck 在发出第一个请求之前,您基本上只需要一些时间来初始化缓存,而 1 秒对我来说很好。如果您担心第一次请求的缓存失败,可以通过多种方式延迟它们。
  • 当我关闭应用程序然后再次打开它时,它会丢失整个缓存。我想打开以前访问过的页面。有办法吗?
猜你喜欢
  • 2014-05-21
  • 2014-04-16
  • 1970-01-01
  • 1970-01-01
  • 2013-12-27
  • 1970-01-01
  • 2011-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多