我有100个网址,我想下载所有这些图片并保存在文档中。为了保存我已经完成,我也可以进行延迟加载,但我无法以最短的时间下载所有内容,GUI不应该挂起。
这样做的合适方法是什么?
由于
答案 0 :(得分:3)
使用SDWebImage。您可以从以下网址下载
https://github.com/rs/SDWebImage
使用异步请求
加载100个图像for(int i=0; i<99; i++)
{
strImage=[[res valueForKey:@"result"] objectAtIndex:i];
if ([[strImage lowercaseString] hasSuffix:@".jpg"] || [[strImage lowercaseString] hasSuffix:@".png"])
{
//[HUD show:YES];
NSURL *url=[[NSURL alloc]initWithString:strImage];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:urlRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
thumbnail.image=[UIImage imageWithData:data];
}];
}
}
答案 1 :(得分:3)
复杂的解决方案可能会变得非常复杂。下载和保存100个URL并不像下载一个图像那样容易100次。
在雄心勃勃但不太聪明的实施中出现的最棘手的问题是内存压力。第三方网络库不会自动为您解决此问题。
一种简单但可行的方法是尝试以性能为代价来避免内存问题,正在执行下载并将所有顺序保存到磁盘操作。这可确保在任何时候只处理一个图像。因此,您可以对此方法所需的最大内存进行安全假设。
解决方案可能如下所示:
假设您有一个异步方法,它从给定的URL加载图像数据:
typedef void (^load_completion_t)(NSData* data, NSError* error);
- (void) loadURL:(NSURL*)url completion:(load_completion_t)completionHandler;
此方法将整个图像数据加载到内存中。这不是最好的方法,但是IFF我们可以假设一个图像总是适合内存,它就变成了一个简单的解决方案。
此外,假设有一种将数据保存到磁盘的同步方法:
- (void) saveData:(NSData*)data;
现在,给定一个URL数组,您可以按顺序加载并保存大量图像,如下所示:
typedef void(^completion_t)(id result, NSError* error);
- (void) saveImagesWithURLs:(NSMutableArray*)urls
completion:(completion_t)completionHandler
{
if ([urls count] > 0) {
NSURL* url = [urls firstObject];
[urls removeObjectAtIndex:0];
[self loadURL:url completion:^(NSData* imageData, NSError*error){
if (imageData) {
[self saveData:imageData];
[self saveImagesWithURLs:urls completion:completionHandler];
}
else {
// handle error
}
}];
}
else {
// finished
if (completionHandler) {
completionHandler(@"Images saved", nil);
}
}
}
上面的方法是“异步循环”:
loadURL:completion
的完成处理程序将调用saveImagesWithURLs:completion:
,就像递归调用一样。但是,这不是一个递归方法:当方法saveImagesWithURLs:completion:
的完成处理程序执行时,saveImagesWithURLs:completion:
已经返回。
鉴于属性是一系列URL:
@property (nonatomic, strong) NSArray* imageURLs;
您可以调用异步循环,如下所示:
[self saveImagesWithURLs:[self.imageURLs mutableCopy]
completion:^(id result, NSError*error){
if (error) {
// handle error
}
else {
// result equals @"Images saved"
}
}];
您可以从主线程调用此方法。它不会阻塞,因为它是异步的。我们还假设,完成处理程序将在私有队列上调用,而不是在主线程上调用。
答案 2 :(得分:0)
更好的用户AFNetworking,它将帮助您异步下载所有图像(无GUI挂起)
答案 3 :(得分:0)
您可以使用 AFHTTPClient 到enqueueBatchOperations,这有一个completionBlock,在所有操作完成后调用。应该是你正在寻找的。 p>