Dispatch Group的使用

六、Dispatch Group的使用

假设有这样一个需求:从网络上下载两张不同的图片,然后显示到不同的UIImageView上去,一般可以这样实现

[java] view plaincopy

  1. // 根据url获取UIImage  

  2. - (UIImage *)imageWithURLString:(NSString *)urlString {  

  3.     NSURL *url = [NSURL URLWithString:urlString];  

  4.     NSData *data = [NSData dataWithContentsOfURL:url];  

  5.     return [UIImage imageWithData:data];  

  6. }  

  7.   

  8. - (void)downloadImages {  

  9.     // 异步下载图片  

  10.     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  

  11.         // 下载第一张图片  

  12.         NSString *url1 = @"http://car0.autoimg.cn/upload/spec/9579/u_20120110174805627264.jpg";  

  13.         UIImage *image1 = [self imageWithURLString:url1];  

  14.           

  15.         // 下载第二张图片  

  16.         NSString *url2 = @"http://hiphotos.baidu.com/lvpics/pic/item/3a86813d1fa41768bba16746.jpg";  

  17.         UIImage *image2 = [self imageWithURLString:url2];  

  18.           

  19.         // 回到主线程显示图片  

  20.         dispatch_async(dispatch_get_main_queue(), ^{  

  21.             self.imageView1.image = image1;  

  22.               

  23.             self.imageView2.image = image2;  

  24.         });  

  25.     });  

  26. }  

虽然这种方案可以解决问题,但其实两张图片的下载过程并不需要按顺序执行,并发执行它们可以提高执行速度。有个注意点就是必须等两张图片都下载完毕后才能回到主线程显示图片。Dispatch Group能够在这种情况下帮我们提升性能。下面先看看Dispatch Group的用处:

我们可以使用dispatch_group_async函数将多个任务关联到一个Dispatch Group和相应的queue中,group会并发地同时执行这些任务。而且Dispatch Group可以用来阻塞一个线程, 直到group关联的所有的任务完成执行。有时候你必须等待任务完成的结果,然后才能继续后面的处理。

下面用Dispatch Group优化上面的代码:

[java] view plaincopy

  1. // 根据url获取UIImage  

  2. - (UIImage *)imageWithURLString:(NSString *)urlString {  

  3.     NSURL *url = [NSURL URLWithString:urlString];  

  4.     NSData *data = [NSData dataWithContentsOfURL:url];  

  5.     // 这里并没有自动释放UIImage对象  

  6.     return [[UIImage alloc] initWithData:data];  

  7. }  

  8.   

  9. - (void)downloadImages {  

  10.     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);  

  11.       

  12.     // 异步下载图片  

  13.     dispatch_async(queue, ^{  

  14.         // 创建一个组  

  15.         dispatch_group_t group = dispatch_group_create();  

  16.           

  17.         __block UIImage *image1 = nil;  

  18.         __block UIImage *image2 = nil;  

  19.           

  20.         // 关联一个任务到group  

  21.         dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  

  22.             // 下载第一张图片  

  23.             NSString *url1 = @"http://car0.autoimg.cn/upload/spec/9579/u_20120110174805627264.jpg";  

  24.             image1 = [self imageWithURLString:url1];  

  25.         });  

  26.           

  27.         // 关联一个任务到group  

  28.         dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  

  29.             // 下载第一张图片  

  30.             NSString *url2 = @"http://hiphotos.baidu.com/lvpics/pic/item/3a86813d1fa41768bba16746.jpg";  

  31.             image2 = [self imageWithURLString:url2];  

  32.         });  

  33.           

  34.         // 等待组中的任务执行完毕,回到主线程执行block回调  

  35.         dispatch_group_notify(group, dispatch_get_main_queue(), ^{  

  36.             self.imageView1.image = image1;  

  37.             self.imageView2.image = image2;  

  38.               

  39.             // 千万不要在异步线程中自动释放UIImage,因为当异步线程结束,异步线程的自动释放池也会被销毁,那么UIImage也会被销毁  

  40.               

  41.             // 在这里释放图片资源  

  42.             [image1 release];  

  43.             [image2 release];  

  44.         });  

  45.           

  46.         // 释放group  

  47.         dispatch_release(group);  

  48.     });  

  49. }  

dispatch_group_notify函数用来指定一个额外的block,该block将在group中所有任务完成后执行


你可能感兴趣的:(Dispatch Group的使用)