2012-01-27 2 views
9

Кажется, что UIWebView не всегда вызывает storeCachedResponse:forRequest: всякий раз, когда он загружает ресурс. Кто-нибудь знает, почему? Я пытаюсь кэшировать изображения с помощью -[NSURLCache storeCachedResponse:forRequest:], он выполняет большую часть работы, но в некоторых случаях UIWebView не вызывает этот метод при загрузке страницы, где на нем есть изображения.UIWebView не всегда вызывает - [NSURLCache storeCachedResponse: forRequest:]

+0

Я заметил это слишком; хотя только * на * устройстве для моего приложения. Когда веб-просмотр загружает запрос из NSURLCache, он, похоже, пропускает тот же самый кеш для активов на этой странице. – Nevir

ответ

4

Как описано hereNSURLConnection не называет storeCachedResponse:forRequest:, если размер файла превышает 50 КБ (52428 байт).
Пробег: ASIHTTPRequestcaching.

+0

Я вижу это для небольших файлов (100s байт). Веб-просмотр также не может вызвать 'cachedResponseForRequest:' – Nevir

+0

@Nevir. См. [Мой ответ] (http://stackoverflow.com/a/9968398/517815). :) – MrGomez

2

Вы проверяли статус HTTP и заголовки кеша? Истекает, Cache-Control и т. Д.? Может быть, сервер отвечает со статусом = 304 без тела ответа?

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

Ответ запрос поставщика Баунти в:

Я вижу это для маленьких файлов (100s байтов), а также. WebView также не называет cachedResponseForRequest:

Я нашел this question, что адресует это поведение непосредственно:

Несмотря документации от Apple indicating otherwise, NSURLCache на прошивке не делают любой диска (флэш) Кэширование на все , Вы можете создать подкласс NSURLCache изменить поведение извлекающих и торговых операций использовать диск (как SDURLCache делают), но из-за следующие серьезные ограничениями, как кэш используется и реализуется, это не работать так же, как и следовало ожидать:

  • NSURLConnection даже не называют storeCachedResponse:forRequest: для файлов в течение примерно 50KB (> = 52428 байт, чтобы быть точным). Это делает подклассификацию NSURLCache бессмысленным для нашего использования (200 КБ изображений), потому что он даже не попадет в кеш. В качестве результата мы должны добавить кеширование вручную на уровне выше NSURLConnection.

  • Даже когда один называет NSURLCache встроенный storeCachedResponse:forRequest: вручную, он сохраняет только отклик в памяти, если это меньше, чем около 180KB. Я проверил это на , вызвав storeCachedResponse вручную и увидев, что до/после currentMemoryUsage не изменился для данных, длина которых превышает примерно 180 КБ. Итак, мы должны написать собственное кэширование памяти LRU.

(выделено мной.)

Это, кажется, отвечает за поведение вызывается из. Поскольку the current accepted answer points out, ASIHTTPRequest является ожидаемым обходным путем для такого поведения.

Однако примечания предостережения в верхней части страницы:

Пожалуйста, обратите внимание, что я больше не работаю в этой библиотеке - вы можете рассмотреть возможность использования что-то еще для новых проектов. :)

Вам следует подумать о том, чтобы полагаться на поддерживаемые библиотеки или, если хотите, внести вклад в эту библиотеку, когда она лежит в основе вашего кода.

+1

Цените это :) (И отличный пример того, где мне следовало бы поискать сложнее) - спасибо за то, что нашли время, чтобы вникнуть в это! – Nevir

+0

@Nevir Нет проблем! Я счастлив, что это было полезно. :) – MrGomez

+0

Кто-нибудь знает, если это все еще имеет место с NSURLSession на iOS 7/8? У меня возникают проблемы с получением NSURLCache для сохранения больших файлов изображений (~ 7 МБ). –

2

Я не знаю, как это работает для UIWebvieuw, но при использовании NSURLRequest максимального размера файла зависит от того, как инициализировать Urlcache (initWithMemoryCapacity: (NSUInteger) memoryCapacity ...) Я просто кэшируюсь файл 2MB

+0

Для меня файл 515 Кбайт .css, запрошенный из UIWebView, может обрабатываться с помощью 'cachedResponseForRequest:' подкласса 'NSURLCache', инициализированного' memoryCapacity: 0 diskCapacity: 1024 * 1024 * 256' – hiroshi

3

NSURLCache работы с двумя различными кэшей: кэш и в-кэш-память на диске

  • Ответы кэшируются в кэш в памяти, если размер ответ под 50Kb и
  • Ответы кэшируются в кэш на диске, если размер отклика над 50kb

При инициализации NSURLCache с diskPath ноль, то кэш на диске не будет активным и storeCachedResponse:forRequest: будет вызываться только для размеры ответов менее 50 кб.

Так настроить Urlcache как этот

[[MYCustomURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024 
          diskCapacity:20 * 1024 * 1024 
          diskPath:@"urlcache.db"]; 
Смежные вопросы