SDWebImage с нетерпением загружает изображения

Я пытаюсь загрузить кучу изображений:

for (NSDictionary *s in things) {
    [manager downloadWithURL:[NSURL URLWithString:s[photo]]
                     options:0
                    progress:nil
                   completed:nil];
}

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

for (NSDictionary *s in things) {
    [manager downloadWithURL:[NSURL URLWithString:s[photo]]
                     options:0
                    progress:nil
                   completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished) { }];
}

тогда он работает нормально. Мой вопрос: почему? Есть лучший способ это сделать? Проход в пустой блок не кажется мне правильным.


person 0xSina    schedule 29.08.2013    source источник


Ответы (3)


Используемый вами API не является правильным.

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

NSMutableArray * urls = [NSMutableArray arrayWithCapacity:things.count];
for (NSDictionary *s in things) {
    [urls addObject:[NSURL URLWithString:s[photo]]];
}
[[SDWebImagePrefetcher sharedImagePrefetcher] prefetchURLs:urls];

В качестве примечания я отправил запрос на вытягивание, который только что был объединен, чтобы обеспечить наличие completedBlock в API, который вы (неправильно) используете, чтобы другие программисты не ввели вас в ту же ошибку.

person Gabriele Petronella    schedule 29.08.2013
comment
К вашему сведению, если вы делаете это несколько раз без блоков завершения, вы, возможно, не захотите использовать sharedImagePrefetcher, так как он отменит текущие операции предварительной выборки перед выполнением новых. Я выделяю новый вместо того, чтобы использовать общий в своем коде. - person Enrico Susatyo; 05.01.2016
comment
@EnricoSusatyo, это здорово. Спасибо, что прояснили это. - person kevinl; 22.12.2016
comment
API имеет недостатки. Prefetcher — это все или ничего сразу. Не всегда возможно (или удобно) заранее формировать кучу запросов. Нет никаких причин, по которым этот общий менеджер не может принимать дополнительные запросы на предварительную выборку, не удаляя ранее поставленные в очередь запросы. Необходимость инициализировать отдельные предварительные выборки является странной. - person CIFilter; 03.05.2017

Если вы внимательно посмотрите на -[SDWebImageManager downloadWithURL:options:progress:completed:] реализацию, вы найдем строки:

if (!url || !completedBlock || (!(options & SDWebImageRetryFailed) && isFailedUrl))
{
    if (completedBlock)
    {
        // Complain about invalid URL, completely irrelevant to us at this point.
        ...
    }
    return operation;
}

Так что да, это ничего не делает, если completionBlock равно nil. Почему? Вероятно, разработчики SDWebImage посчитали этот метод бесполезным без передачи этого параметра. Вам лучше создать проблему GitHub, чтобы спросить их.

person iHunter    schedule 29.08.2013
comment
Это имеет смысл. Если вы ничего не делаете с изображением, зачем вы его вообще используете? Однако они должны использовать утверждение параметра, чтобы обеспечить это. - person Gabriele Petronella; 29.08.2013
comment
@GabrielePetronella Я согласен, но способ использования 0xSina совершенно естественен. Это недостаток дизайна. - person iHunter; 29.08.2013
comment
Они должны создать исключение, чтобы сообщить об этом разработчику. Я делаю запрос на вытягивание. - person Gabriele Petronella; 29.08.2013
comment
@GabrielePetronella Я хочу загрузиться. У меня есть таблица с кучей изображений, 90% из них не отображаются, пока пользователь не прокрутит вниз. Я хочу предварительно загрузить их. Очевидно, мне ПОКА не нужны изображения, поэтому мне не нужен блок. Я просто хочу убедиться, что изображения загружены. - person 0xSina; 29.08.2013
comment
@GabrielePetronella Думаю, я спрашиваю, если бы вы хотели загрузить изображения (убедитесь, что они загружены и кэшированы), как бы вы это сделали? - person 0xSina; 29.08.2013
comment
@0xSina, посмотри мой ответ. - person Gabriele Petronella; 29.08.2013

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

SDWebImagePrefetcher.shared().prefetchURLs(urlArray)
person Justin Vallely    schedule 04.02.2018