简体   繁体   English

UIWebView并不总是调用 - [NSURLCache storeCachedResponse:forRequest:]

[英]UIWebView doesn't always call -[NSURLCache storeCachedResponse:forRequest:]

It seems that UIWebView doesn't always call storeCachedResponse:forRequest: whenever it's loading a resource. 似乎UIWebView并不总是调用storeCachedResponse:forRequest:每当它加载资源时。 Does anyone know why? 有谁知道为什么? I am trying to cache images by using -[NSURLCache storeCachedResponse:forRequest:] , it does most of the job fine, however in some cases UIWebView doesn't call this method on page load where there are actually images on it. 我试图通过使用-[NSURLCache storeCachedResponse:forRequest:]缓存图像,它完成大部分工作,但在某些情况下, UIWebView不会在页面加载上调用此方法,其中实际上有图像。

Answering the bounty provider's query: 回答赏金提供者的查询:

I'm seeing this for small files (100s of bytes) as well. 我也看到了这个小文件(100字节)。 The webview also fails to call cachedResponseForRequest: webview也无法调用cachedResponseForRequest:

I found this question that addresses this behavior directly: 我发现这个问题直接解决了这个问题

Despite Apple's documentation indicating otherwise , NSURLCache on iOS doesn't do any disk (flash) caching at all. 尽管Apple的文档另有说明NSURLCache iOS上的NSURLCache根本不进行任何磁盘(闪存)缓存。 You can subclass NSURLCache to change the behaviour of the fetch and store operations to use the disk (like SDURLCache does), but due to the following severe limitations of how the cache is used and implemented, this doesn't work as well as you'd expect: 您可以将NSURLCache子类NSURLCache以更改获取和存储操作的行为以使用磁盘(如SDURLCache那样),但由于以下严格限制了如何使用和实现缓存,这不会像您那样有效。 d期望:

  • NSURLConnection doesn't even call storeCachedResponse:forRequest: for files over about 50KB (>= 52428 bytes, to be exact). NSURLConnection甚至不调用storeCachedResponse:forRequest:对于大约50KB(> = 52428字节,确切地说)的文件。 This makes subclassing NSURLCache pointless for our use (200KB images), because it won't even get to the cache. 这使得子类NSURLCache对我们的使用毫无意义(200KB图像),因为它甚至不会进入缓存。 As a result, we have to add caching manually at a level above NSURLConnection . 因此,我们必须在NSURLConnection以上的级别手动添加缓存。

  • Even when one calls the NSURLCache's built-in storeCachedResponse:forRequest: manually, it only stores the response in memory if it's less than about 180KB. 即使一个人调用NSURLCache的内置storeCachedResponse:forRequest:手动,它只会将响应存储在内存中,如果它小于大约180KB。 I tested this by calling storeCachedResponse manually and seeing that the before/after currentMemoryUsage didn't change for data lengths above about 180KB. 我通过手动调用storeCachedResponse,看到这个测试的前/后currentMemoryUsage没有为数据长度超过大约180KB改变。 So we have to write our own LRU memory caching too. 所以我们也必须编写自己的LRU内存缓存。

(Emphasis mine.) (强调我的。)

This seems to be responsible for the behavior being called out. 这似乎是被召唤出来的行为的原因。 As the current accepted answer points out , ASIHTTPRequest is the expected workaround for this behavior. 正如当前接受的答案指出的那样ASIHTTPRequest是此行为的预期解决方法。

However, note the caveat at the top of the page: 但是,请注意页面顶部的警告:

Please note that I am no longer working on this library - you may want to consider using something else for new projects. 请注意,我不再使用此库 - 您可能需要考虑使用其他新项目。 :) :)

You should consider relying on supported libraries or, if you prefer, contributing back to this library once it underlies your code. 您应该考虑依赖受支持的库,或者,如果您愿意,一旦它成为您的代码的基础,就会回馈此库。

As described here NSURLConnection doesn't call storeCachedResponse:forRequest: if file size over 50kb(52428 bytes). 如此处所述 NSURLConnection不调用storeCachedResponse:forRequest:如果文件大小超过50kb(52428字节)。
Try ASIHTTPRequest caching . 尝试ASIHTTPRequest 缓存

NSURLCache works with two different caches: on-disk cache and in-memory cache NSURLCache使用两种不同的缓存:磁盘缓存和内存缓存

  • Responses will be cached to in-memory cache if the response size is under 50kb and 如果响应大小低于 50kb,响应将被缓存到内存缓存中
  • Responses will be cached to on-disk cache if the response size is over 50kb 如果响应大小超过 50kb,响应将缓存到磁盘缓存

If you initialize NSURLCache with diskPath nil then the on-disk cache will not be active and storeCachedResponse:forRequest: will only be called for response sizes that are under 50kb. 如果使用diskPath nil初始化NSURLCache,则磁盘缓存将不会处于活动状态,并且只会针对50kb以下的响应大小调用storeCachedResponse:forRequest:

So configure your URLCache like this 所以像这样配置你的URLCache

[[MYCustomURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024 
                          diskCapacity:20 * 1024 * 1024 
                          diskPath:@"urlcache.db"];

我不确定UIWebvieuw是如何工作的,但是当你使用NSURLRequest时,文件的最大大小取决于你如何初始化URLCache(initWithMemoryCapacity:(NSUInteger)memoryCapacity ...)我刚刚缓存了一个2MB的文件

Have you checked HTTP status and cache headers? 您是否检查过HTTP状态和缓存标头? Expires, Cache-Control etc? 过期,缓存控制等? Maybe a server answers with status=304 without any response body? 也许服务器回答status = 304而没有任何响应体?

- (void)connection:(NSURLConnection *)conn didReceiveResponse:(NSURLResponse *)aResponse 
{
  NSLog(@"CODE: %d", ((NSHTTPURLResponse *)aResponse).statusCode);
  NSLog(@"HEADERS: %@", ((NSHTTPURLResponse *)aResponse).allHeaderFields);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM