您的位置:首页 > 其它

如何利用GCD Group批量下载文件

2014-05-07 21:24 393 查看


未命名

小引:有时候,我们在开发iOS程序时,需要批量下载一些文件(比如图片),只有当全部文件下载完毕,我们才做相应的处理(界面更新,通知用户等)——也就是说虽然有多个文件在下载,但是我们只需要收到一个全部下载完毕的通知。

在网上搜索了一番,感觉使用GCD的高级功能Group,比较方便。下面写了一个小Demo,实现了多个图片文件的异步并发下载,缓存到本地,并显示到界面中。

参考了唐巧的一篇博文:使用GCD

另外感兴趣的同学可以看看下面几篇GCD相关文章,非常不错:

raywenderlich:Multithreading
and Grand Central Dispatch on iOS for Beginners Tutorial

苹果官网:Grand
Central Dispatch (GCD) Reference
 和 Concurrency
Programming Guide

Demo可以到Github上下载:

 https://github.com/BeyondVincent/DownloadImage_GCD

下面是使用GCD Group的关键代码:
- (IBAction)downloadAction:(UIButton *)sender
{
[self resetImage];
self.status.text = @"正在下载";
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t downloadImage = dispatch_group_create();

for (ImageInfo *info in self.imageList) {
NSString* imagePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:info.imageName];

NSFileManager *fileManager = [NSFileManager defaultManager];
// 如果本地不存在图片,则从网络中下载
if (![fileManager fileExistsAtPath:imagePath]) {
dispatch_group_async(downloadImage, queue, ^{
NSLog(@"Starting image download:%@", imagePath);
// URL组装和编码
NSString *urlString = [NSString stringWithFormat:@"%@/%@", self.baseUrl, info.imageName];
NSURL *url = [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSLog(@"image download from url:%@", urlString);

// 开始下载图片
NSData *responseData = [NSData dataWithContentsOfURL:url];
// 将图片保存到指定路径中
[responseData writeToFile:imagePath atomically:YES];
// 将下载的图片赋值给info
info.image = [UIImage imageWithData:responseData];
NSLog(@"image download finish:%@", imagePath);
});
} else { // 将本地图片加载到systemInfo.MyImage
info.image = [UIImage imageWithData:[NSData dataWithContentsOfFile:imagePath]];
}
}
dispatch_group_notify(downloadImage, dispatch_get_main_queue(), ^{
// 图片加载完毕之后,显示出来
self.status.text = @"图片文件下载并缓存完毕";
[self showImage];
});
}


上面关键的代码是dispatch_group_async(并行执行线程1)和dispatch_group_notify(全部下载完毕,由此进行回调通知)。在for语句中循环开启了6个并发任务。当6个任务完成之后,调用showImage方法,将图片显示出来。

下面是运行效果图(第一个图为程序刚刚启动时的效果,第二个为点击开始异步下载图片按钮之后的效果):


QQ20130502-3



QQ20130502-2

 

在写本Demo的时候,遇到了以下两个问题
关于图片的加载,UIImage中的imageNamed:方法只能加载程序main bundle中的图片。要想加载Document中的图片,需要使用UIImage的imageWithData方法。更多相关资料可以阅读苹果官方介绍:UIImage
NSURL URLWithString:myString returns Nil。在初始化NSURL实例对象是,一直都返回Nil。后来在这里(Here)发现原来是URL中含有特殊字符,需要进行编码处理,照着链接中的方法搞定。

_________________

本文由破船原创

转载请注明出处:BeyondVincent的博客

_________________
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: