如何在iOS中asynchronous下载多个图像,而不影响UI?

我有100个url,我想下载所有这些图像并保存在文档中。 为了节省我已经做了,也可以做懒加载,但我无法用最less的时间下载所有的graphics用户界面不应该挂起。

这样做有什么合适的方法?

谢谢

使用SDWebImage。 你可以从下面的url下载它

https://github.com/rs/SDWebImage

用于使用asynchronous请求加载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]; }]; } } 

复杂的解决scheme可能会变得相当复杂 下载和保存100个URL不像下载一个图像100次简单。

内存压力是在雄心勃勃但不太聪明的实现中最棘手的问题。 第三方networking库不会自动为您解决这个问题。

一个简单的 – 但是可行的 – 试图以一点点性能为代价来避免内存问题的方法是按顺序执行下载和保存到磁盘操作。 这确保了,只有一个图像将被随时处理。 因此,您可以对此方法所需的最大内存进行安全假设。

解决scheme可能如下所示:

假设你有一个asynchronous的方法从给定的URL加载图像数据:

 typedef void (^load_completion_t)(NSData* data, NSError* error); - (void) loadURL:(NSURL*)url completion:(load_completion_t)completionHandler; 

这种方法将把整个图像数据加载到内存中。 这不是最好的方法,但是IFF我们可以假设一张图片总是适合记忆,这成为一个简单的解决scheme。

此外,假设有一种将数据保存到磁盘的同步方法:

 - (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); } } } 

上面的方法是一个“asynchronous循环”:

loadURL:completion的完成处理程序将调用saveImagesWithURLs:completion:就像recursion调用一样。 但是,这不是recursion方法:当方法saveImagesWithURLs:completion:的完成处理程序被执行时, saveImagesWithURLs:completion:已经返回。

给定一个属性是一个URL数组:

 @property (nonatomic, strong) NSArray* imageURLs; 

你可以调用asynchronous循环,如下所示:

 [self saveImagesWithURLs:[self.imageURLs mutableCopy] completion:^(id result, NSError*error){ if (error) { // handle error } else { // result equals @"Images saved" } }]; 

你可以从主线程调用这个方法。 它不会阻塞,因为它是asynchronous的。 我们还假设,完成处理程序将在私有队列中调用,而不是在主线程上调用。

更好的用户AFNetworking,它会帮助你下载所有的图像asynchronous(没有GUI挂起)

https://github.com/AFNetworking/AFNetworking

您可以使用AFHTTPClient来排队批处理,并有一个completionBlock,当所有操作完成时调用。 应该是你正在寻找的。