Ios SDWebImage快速加载图像

Ios SDWebImage快速加载图像,ios,objective-c,cocoa-touch,sdwebimage,Ios,Objective C,Cocoa Touch,Sdwebimage,我正在尝试加载一堆图像: for (NSDictionary *s in things) { [manager downloadWithURL:[NSURL URLWithString:s[photo]] options:0 progress:nil completed:nil]; } 它不会下载这些图片。但是,如果我传入一个空的完成块,如下所示: for (NSDi

我正在尝试加载一堆图像:

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) { }];
}

那么它就可以正常工作了。我的问题是:为什么?有更好的方法吗?在我看来,穿过一个空街区是不对的

如果你仔细观察,你会发现:

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问题来询问他们。

您使用的API不正确

要预取图像并将其存储在缓存中,请使用专用的
SDWebImagePrefetcher

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


作为旁注,我提交了一个pull请求(刚刚合并),以强制在您(mis)使用的API中存在一个
completedBlock
,这样其他程序员就不会让您犯同样的错误了。

SDWebImage已修复了完成块问题,现在可以通过一行Swift:

SDWebImagePrefetcher.shared().prefetchURLs(urlArray)

这是有道理的。如果您没有对图像做任何操作,那么为什么要首先使用它?不过,他们应该使用参数断言来强制执行这一点。@GabrielePetronella我同意,但我认为使用它的方式是完全自然的。这是一个设计缺陷。他们应该提出一个异常来通知开发者。我正在请求拉车。@GabrielePetronella我想拉车。我有一个包含大量图像的tableview,90%的图像在用户向下滚动之前不会显示。我想先加载它们。显然,我还不需要图像,所以我不需要块。我只是想确保图像已加载。@GabrielePetronella我想我要问的是,如果你想立即加载图像(确保它们已下载并缓存),你会怎么做?仅供参考,如果你在没有完成块的情况下多次这样做,你可能不想使用
sharedImagePrefetcher
,因为它将在执行新的预取操作之前取消当前正在运行的预取操作。我分配了一个新的,而不是在我的代码中使用共享的。@EnricoSusatyo太棒了。谢谢你澄清。API有缺陷。预取程序是一次完成全部或全部完成。提前批处理一堆请求并不总是可能的(或方便的)。没有理由说这个共享管理器不能接受额外的预回迁请求,而不清除任何以前的预回迁请求。必须初始化单个预取器是很奇怪的。