2009-12-08 3 views
11

Я пытаюсь понять, как использовать платформу загрузки URL-адресов для загрузки URL-адресов, использующих кеширование.Использует ли NSURLConnection NSURLCache?

Я использую NSURLConnections и кормя их NSURLRequests. Я даже установил cachePolicy для этих запросов в NSURLRequestReturnCacheDataElseLoad. В первый раз, когда я загружаю запрос, он автоматически попадает в кеш (это [NSURLCache sharedCache]). Но в следующий раз, когда я загружаю тот же запрос, NSURLConnection, похоже, игнорирует то, что находится в кеше, и перезагружает данные.

Должен ли я вручную применять поиск кеша и возвращать кэшированные данные? Неужели NSURLConnection не делает этого? Или есть какой-то способ заставить инфраструктуру использовать кеш без проблем?

UPDATE: Попробовал следующий без успеха:

  • Настройка политики кэширования запроса на NSURLRequestReturnCacheDataElseLoad вместо NSURLRequestUseProtocolCachePolicy
  • Повторное использование объекта запроса вместо того, чтобы сделать новый
  • Использование +[NSURLConnection sendSynchronousRequest:returningResponse:error:] вместо асинхронного погрузки
+2

Вы подаете им тот же объект NSURLRequest? В документации указано, что NSURLCache работает путем сопоставления определенного объекта NSURLRequest с указанными данными ответа, поэтому вполне возможно, что даже если вы делаете запрос на тот же URL-адрес, это все равно приведет к промаху в кеше. – ImHuntingWabbits

+0

Нет, я создаю новый NSURLRequest. Но когда я делаю '[[NSURLCache sharedURLCache] cachedResponseForRequest:]' с этим новым объектом запроса, есть кешированный ответ. Поэтому NSURLCache каким-то образом знает, что запросы одинаковы. – jasoncrawford

+0

PS: Я попытался повторно использовать объект NSURLRequest. Не имеет значения. – jasoncrawford

ответ

0

Это будет ind eed использует NSURLCache автоматически, по крайней мере в некоторых случаях. Конечно, это происходит в следующем коде:

EDIT - работает в приложении OS X 10.6 какао, а не iPhone (неправильно истолковывать вопрос)

#import <Foundation/Foundation.h> 

int main (int argc, const char * argv[]) { 

    // run request with default cache policy 
NSMutableURLRequest *req=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://en.wikipedia.org/"]]; 
NSData *data=[NSURLConnection sendSynchronousRequest:req returningResponse:nil error:nil]; 
NSLog(@"Received %d bytes", [data length]); 

sleep(10); 

    // now run it asking it to use the cache 
[req setCachePolicy:NSURLRequestReturnCacheDataElseLoad]; 
data=[NSURLConnection sendSynchronousRequest:req returningResponse:nil error:nil]; 
NSLog(@"Received %d bytes", [data length]); 

    return 0; 
} 
+0

Интересно, спасибо. Для чего это стоит, тем не менее, я выполняю асинхронные запросы - не уверен, что это важно. – jasoncrawford

+0

ОК, поэтому я действительно пробовал это, и он не работает для меня. Второй запрос по-прежнему занимает несколько сотен миллисекунд, и если я использую политику кэша 'NSURLRequestReturnCacheDataDontLoad', он возвращает 0 байт. Кроме того, если я запрашиваю кеш непосредственно между ними, используя '[[NSURLCache sharedURLCache] cachedResponseForRequest: req]', он возвращает nil. Итак, для меня нет кэширования. Я бегу в симуляторе iPhone, моделируя OS 3.0 (также пробовал 3.1.2), под Snow Leopard. – jasoncrawford

+1

Правильно, возможно, это связано с тем, что я просто бегу прямо под OS X. Я не заметил тег iphone - извините. –

0

Вы пробовали баловаться с методом connection:willCacheResponse:? Согласно URL Loading System documentation: «По умолчанию данные для подключения кэшируются в соответствии с поддержкой, предоставляемой подклассом NSURLProtocol, который обрабатывает запрос. NSURLConnection Delegationdelegate может дополнительно уточнить это поведение путем реализации соединения: willCacheResponse :."

+1

Да, я попробовал реализовать 'connection: willCacheResponse:' - не помогает. Этот метод действительно вызван, и - вот кикер - ответ определенно заканчивается в кеше. После первого запроса '[[NSURLCache sharedCache] cachedResponseForRequest: request]' возвращает кешированный ответ. Но если я затем инициализирую NSURLConnection с тем же запросом, он извлекается заново, а не попадает в кеш. – jasoncrawford

+0

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

6

ПРИМЕЧАНИЕ IOS 5 года обеспечить sharedURLCache, который имеет как памяти и дисковой емкости.

Ничто не кэшировать, если вы установите NSURLCache иметь некоторую емкость:

// A 10MB cache. This a good avatar-image-cache size but might be too 
// large for your app's memory requirements. YMMV. 
[[NSURLCache sharedURLCache] setMemoryCapacity:1024*1024*10]; 

по умолчанию экземпляр iPhone NSURLCache отказывается когда-либо кэш на диске. если вам нужно это поведение, вы должны подклассом NSURLCache и реализовать свой собственный кеш диска. Я нашел множество примеров дисковых кэшей на GitHub, хотя ни один из них не делает полностью необходимый «чернослив» шаг удовлетворительно IMHO.

+1

Похоже, что [[NSURLCache sharedURLCache] setMemoryCapacity: 1024 * 1024 * 10] работает, но вы должны вызывать его каждый раз, когда делаете запрос, потому что, когда я его однажды вызывал в своем AppDelegate, поведение кэша было абсолютно случайным между запуском приложений (иногда это сработало, иногда нет). –

+0

Даже если вы не настроите кеш явно, NSURLCache все еще создает файл db и сохраняет этот контент! – Abhinit

+1

@Abhinit да, мой ответ предшествует iOS 5. С тех пор кеш всегда настроен, если вы его не отключили. – mxcl

Смежные вопросы