Что происходит с кэшированными изображениями SDWebImage в моем приложении при изменении файла изображения на сервере? - PullRequest
48 голосов
/ 19 мая 2011

Я использую библиотеку SDWebImage для кэширования веб-изображений в моем приложении:

https://github.com/rs/SDWebImage/blob/master/README.md

Текущее использование:

[imageView setImageWithURL:[NSURL URLWithString:profilePictureUrl] placeholderImage:[UIImage imageNamed:@"placeholder.png"]];

У меня вопрос: что произойдет, когда изображение будет кэшировано, а затем через пару дней этот файл изображения на сервере будет обновлен новым образом?

В данный момент мое приложение все еще отображает кэшированное изображение.

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

Если у кого-то есть опыт использования этой конкретной библиотеки, то любая помощь будет принята с благодарностью.

Заранее спасибо.

Ответы [ 10 ]

64 голосов
/ 24 мая 2011

Я посмотрел на исходный код.Он обрабатывает метод setImageWithURL следующим образом:

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

Тамне отправляется запрос, чтобы спросить удаленный сервер, есть ли новая версия, в то время как на диске есть что-то старое, например, использование ETags протокола HTTP.

Копание немного глубже времени кэшав SDImageCache.m

static NSInteger cacheMaxCacheAge = 60*60*24*7; // 1 week

установлено статическое значение. Его нельзя изменить с помощью установщика.

Так что, пока изображение в кэше является действительнымSDWebImage lib не будет загружать ничего нового.Через неделю он загрузит ваше измененное изображение.

23 голосов
/ 20 декабря 2013

Вы можете использовать options параметр.

Swift версия:

imageView.sd_setImage(with: URL(string: URLWithString:profilePictureUrl),
                      placeholderImage: UIImage(named: "placeholder"),
                      options: .refreshCached,
                      completed: nil)

Версия Objective-C:

[imageView sd_setImageWithURL:[NSURL URLWithString:profilePictureUrl]
             placeholderImage:[UIImage imageNamed:@"placeholder.png"]
             options:SDWebImageRefreshCached
             completed: nil];

Ура!

10 голосов
/ 05 января 2013

Проблема со старением SDImageCache (который теперь имеет установщик: maxCacheAge) заключается в том, что SDWebImage никогда не делает с ним ничего проактивного. Вам нужно вызвать cleanDisk самостоятельно в какой-то момент, чтобы удалить старые данные из кэша. Примечание: SDWebImage вызывает cleanDisk, когда приложение завершает свою работу, но приложениям не гарантируется получение уведомления о завершении из ОС.

7 голосов
/ 06 сентября 2011
    NSURL *imageUrl = nil;
    NSDate *lastUpdate = [[NSUserDefaults standardUserDefaults] objectForKey:@"lastUpdate"];
    NSDate *currentDate = [NSDate date];

    if (lastUpdate == nil 
        || ![lastUpdate isKindOfClass:[NSDate class]] 
        || [currentDate timeIntervalSinceDate:lastUpdate] > 60 * 60 *24) {
            [[NSUserDefaults standardUserDefaults] setObject:currentDate forKey:@"lastUpdate"];
            NSString *urlString = [NSString stringWithFormat:@"http://yourdomain.com/image/image.png?%f", [currentDate timeIntervalSince1970]];
            imageUrl = [NSURL URLWithString:urlString];
    }
6 голосов
/ 10 сентября 2015

Если вы хотите изменить длительность кэша по умолчанию в Swift. Установите это в вашем AppDelegate.

Версия 3:

SDWebImageManager.sharedManager().imageCache.maxCacheAge = CACHE_TIME_IN_SECONDS

Версия 4:

SDWebImageManager.shared().imageCache?.config.maxCacheAge = CACHE_TIME_IN_SECONDS

-

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

4 голосов
/ 24 августа 2015

SDWebImage по умолчанию использует агрессивное кэширование. Но теперь они дают возможность уважать ваши заголовки управления кэшированием HTTP и получать последнюю версию.

Для этого у них есть новый метод, в котором в параметрах вы можете передать SDWebImageRefreshCached

[imageView sd_setImageWithURL:[NSURL URLWithString:@"https://graph.facebook.com/xyz/picture"]
             placeholderImage:[UIImage imageNamed:@"avatar-placeholder.png"]
                      options:SDWebImageRefreshCached];

Вы можете найти полную информацию о методе и объяснение здесь .

4 голосов
/ 30 сентября 2014

Ниже то, что я наблюдал.

  1. Если имя / путь к изображению совпадают, SDWebImage не будет загружать его снова в течение 1 недели.

  2. Независимо от имени изображения, SDWebImage повторно загрузит изображение через 1 неделю (с момента его загрузки).

    static NSInteger cacheMaxCacheAge = 60*60*24*7; // 1 week

  3. У них есть одна База данных, где хранятся все изображения URL. Для них URL-адрес изображения похож на первичный ключ (уникальный ключ).

В общем, что они делают, если URL-адрес изменен и отсутствует в БД, скачайте его.

С моей точки зрения, то, что они делают, ПРАВИЛЬНО. Ex. Если вы загружаете изображение, скажем, для пользователя А, имя изображения должно быть изменено, и это является основным. Я знаю, что некоторые разработчики предпочитают, чтобы имя изображения было одинаковым (как и у userA.png всегда).

3 голосов
/ 04 мая 2018

Поток SDWebImage:

1) SDWebImage кэширует изображение, полученное с сервера

2) SDWebImage использует url-ключ для получения изображения из кэша

3) SDWebImage проверяет:

, если способен получить изображение из кэша - ОК

, если нет (например, URL былизменено) - не удалось получить изображение из кеша

, поэтому на самом деле вы получите пустые ImageView (и) и SDWebImage должен снова получить изображения с сервера

2 голосов
/ 03 августа 2017

Последний Swift 3.0 * и SDWebImage

SDWebImageManager.shared().imageCache?.deleteOldFiles(completionBlock: nil)
1 голос
/ 22 февраля 2016

Как я читал в readme SDWeb в git, Это может помочь:

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

[imageView sd_setImageWithURL:[NSURL URLWithString:@"https://graph.facebook.com/olivier.poitrey/picture"]
                 placeholderImage:[UIImage imageNamed:@"avatar-placeholder.png"]
                          options:SDWebImageRefreshCached];
...