2013-07-27 1 views
2

У меня есть простой метод, который принимает URL и загружает с сервера:поведение кэширования Странно NSURLConnection

- (void)loadURL:(NSString*)url 
{ 
    NSMutableURLRequest* request = [[NSMutableURLRequest alloc] init]; 
    request.HTTPMethod = @"GET"; 
    request.URL = [NSURL URLWithString:url]; 

    NSHTTPURLResponse* response; 
    [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil]; 
} 

Сервера возвращает ответ с максимальным возрастом 1 дня.

Проблема заключается в том, что, когда я бегу эти 3 линии несколько раз, 2 из них случайно пропустить кэш и перезагрузить ответ:

[self loadURL:@"http://192.168.0.105:8080/users/51bdbc73808897302f000001/avatar?size=200x200&access_token=abcdefghijklmnopqrstuvwxyzzp77eDLqub3EWfXGe4c09RoyipmXgcENwfE6EV9yzvgp5VTSZww"]; 
[self loadURL:@"http://192.168.0.105:8080/users/51ee9d4e263d08fe04000003/avatar?size=200x200&access_token=abcdefghijklmnopqrstuvwxyzzp77eDLqub3EWfXGe4c09RoyipmXgcENwfE6EV9yzvgp5VTSZww"]; 
[self loadURL:@"http://192.168.0.105:8080/users/51d17b81de38c60b20000006/avatar?size=200x200&access_token=abcdefghijklmnopqrstuvwxyzzp77eDLqub3EWfXGe4c09RoyipmXgcENwfE6EV9yzvgp5VTSZww"]; 

Если я добавить некоторые случайные уникальные данные (& х, & у, & г) в строке запроса каждого запроса в это исправляет проблему:

[self loadURL:@"http://192.168.0.105:8080/users/51bdbc73808897302f000001/avatar?size=200x200&access_token=abcdefghijklmnopqrstuvwxyzzp77eDLqub3EWfXGe4c09RoyipmXgcENwfE6EV9yzvgp5VTSZww&x"]; 
[self loadURL:@"http://192.168.0.105:8080/users/51ee9d4e263d08fe04000003/avatar?size=200x200&access_token=abcdefghijklmnopqrstuvwxyzzp77eDLqub3EWfXGe4c09RoyipmXgcENwfE6EV9yzvgp5VTSZww&y"]; 
[self loadURL:@"http://192.168.0.105:8080/users/51d17b81de38c60b20000006/avatar?size=200x200&access_token=abcdefghijklmnopqrstuvwxyzzp77eDLqub3EWfXGe4c09RoyipmXgcENwfE6EV9yzvgp5VTSZww&z"]; 

Кроме того, если я уменьшить длину строки запроса до 80 символов он исправляет эту проблему, а также:

[self loadURL:@"http://192.168.0.105:8080/users/51bdbc73808897302f000001/avatar?size=200x200&access_token=abcdefghijklmnopqrstuvwxyzzp77eDLqub3EWfXGe4c09Royipm"]; 
[self loadURL:@"http://192.168.0.105:8080/users/51ee9d4e263d08fe04000003/avatar?size=200x200&access_token=abcdefghijklmnopqrstuvwxyzzp77eDLqub3EWfXGe4c09Royipm"]; 
[self loadURL:@"http://192.168.0.105:8080/users/51d17b81de38c60b20000006/avatar?size=200x200&access_token=abcdefghijklmnopqrstuvwxyzzp77eDLqub3EWfXGe4c09Royipm"]; 

Что происходит? Это ошибка в iOS? Как я могу это исправить?

P.S: Я проверил это в пустом приложении без дополнительного материала, как на прошивке 5 и 6.

+0

Как проверить, читает ли система URL загрузки из кэша или получает доступ к удаленному серверу? Какие заголовки управления кешем установлены в запросе? Использует ли клиент кеш? Обратите внимание, что кеш может игнорировать указанное время истечения срока действия сервера. – CouchDeveloper

+0

@CouchDeveloper Я запускаю 'tail -f server.log | grep avatar ', чтобы видеть запросы в реальном времени по мере их поступления. Сервер устанавливает заголовок Cache-Control со значением' max-age = 86400 '. И клиент имеет набор NSURLCache. – soheilpro

+0

Вам нужно проверить заголовки управления кешем из запроса. Как уже упоминалось, клиент может игнорировать дату истечения срока действия, установленную с сервера или прокси. Кэширование довольно сложно: [13 Кэширование в HTTP] (http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html) – CouchDeveloper

ответ

0

Установите поведение кэширования в NSURLRequest с requestWithURL:cachePolicy:timeoutInterval:. Попробуйте:

- (void)loadURL:(NSString*)url 
{ 
    NSURL *url = [NSURL URLWithString:url]; 
    NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy: NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10.0]; 

    NSHTTPURLResponse* response; 
    [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil]; 
} 

Возможно также использовать NSURLRequestReloadIgnoringLocalAndRemoteCacheData для cachePolicy.

+0

Это изменит политику кэширования в том, что она обходит ее, но не объясняет, почему кеш не используется иногда, когда это необходимо. – CouchDeveloper