Я пытаюсь диагностировать очень серьезную ошибку, которая приводит к загрузке и кэшированию неправильного изображения в моем iOS-клиенте для заданного URL-адреса. Я загружаю сетку миниатюр, а в некоторых случаях для ячейки сетки появляется неправильное эскизное изображение. Я использую популярную структуру изображений SDWebImage для управления загрузкой, кэшированием и т. Д. Следующие фрагменты кода из библиотеки SDWebImage.NSURLConnection didReceiveResponse для неправильного подключения
Я вижу обратный вызов
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
, который содержит ответ, который не для URL я просил, но вместо этого на другой URL. Я знаю это, потому что в заголовках запросов на моем (локальном) сервере я включил имя файла и ETag в заголовки запроса. Я написал следующий код, чтобы убедиться, что запрос и ответ совпасть:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
NSString *etag = ((NSHTTPURLResponse *)response).allHeaderFields[@"ETag"];
NSString *s3FileName = ((NSHTTPURLResponse *)response).allHeaderFields[@"file_name"];
assert([self.request.URL.absoluteString rangeOfString:s3FileName].location != NSNotFound);
// proceed with processing
}
Это утверждение теперь не удается, то есть имя файла в объекте ответа не соответствует имени файла в запросе.
Я также проверил, если возможно, была ошибка в NSURLCache, так что я сделал это:
NSCachedURLResponse *cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:self.request];
NSLog(@"Cached response for %@ is %@", [self.request.URL absoluteString], cachedResponse);
Кэшированного ответ всегда пустой.
На сервере я вижу, что клиент никогда, по сути, не запрашивал URL-адрес до получения вызова didReceiveResponse.
Время выглядит следующим образом:
- Клиент запрашивает http://localhost/1.jpg
- Клиент запрашивает http://localhost/2.jpg
- сервер отвечает на запрос о 1.jpg
- didReceiveResponse вызывается для запроса, соответствующего 2.jpg , но с данными для 1.jpg. CORRUPTION
- didReceiveResponse вызывается для запроса, соответствующего 1.jpg, с данными для 1.jpg.
Клиент теперь неправильно отображает одно и то же изображение в двух местах.
Вот скриншот того, что стек выглядит в то время я получаю обратный вызов didReceiveResponse
с данными из другого запроса:
Я подтвердил, что делегат на [self.connection start]
спички делегат на этапе didReceiveResponse
и что NSURLRequest
также соответствует как в начале, так и в времени ответа на прием.
Единственное, что я могу придумать, это то, что в библиотеке NSURLConnection есть некоторая коррупция. Хотя я понимаю, что NSURLSession - это новая Apple-санкционированная библиотека, я глубоко отлаживаю внутренности SDWebImage (буквально, SDWebImageDownloaderOperation) и не могу заменить эту библиотеку или ее использование NSURLConnection.
Эта проблема периодически повторялась за последние 18 месяцев, но сегодня я смог ее воспроизвести в течение нескольких секунд каждый раз на одном из моих более старых/более медленных тестовых устройств, iPhone 4S, попав на локальный тестовый сервер ,
Может ли кто-нибудь объяснить мою ситуацию, когда NSURLConnection случайным образом предоставляет ответ на другое соединение?
Я имел этот точный вопрос раз, и оказался, что проблема с балансировкой нагрузки моего сервера - это посылает ответы на неправильные соединения. NSURLConnection проверен и надежен; Я сомневаюсь, что это преступник. –
Hace вы проверили, что ваш тестовый сервер поддерживает HTTP-конвейеру? Любые обновления по этой проблеме? – pdrcabrod