队列组的应用
开发中,如果我们需要同时开启多条线程下载数据,并且等待这多条线程执行完毕,即数据下载完成后,再来对这多个数据进行操作。这样的需求在项目开发中还是比较常见的,那么有什么比较好的方法可以实现这样的需求呢?答案是:队列组。
下面就针对这个问题分别展开研究。
1、异步下载两种图片,分别合并之后再回到主线程刷新UI
/// 异步下载两种图片,分别合并之后再回到主线程刷新UI
- (void)mergedImages1 {
// 异步下载
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 1.下载第1张
UIImage *image1 = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:ImgUrl1]]];
// 2.下载第2张
UIImage *image2 = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:ImgUrl2]]];
// 3.合并图片
// 开启一个位图上下文
UIGraphicsBeginImageContextWithOptions(image1.size, NO, 0.0);
// 绘制第1张图片
CGFloat image1W = image1.size.width;
CGFloat image1H = image1.size.height;
[image1 drawInRect:CGRectMake(0, 0, image1W, image1H)]
; // 绘制第2张图片 CGFloat image2W = image2.size.width; CGFloat image2H = image2.size.height * 0.5; CGFloat image2Y = image1H * 0.5;
[image2 drawInRect:CGRectMake(0, image2Y, image2W, image2H)]
; // 得到上下文中的图片 UIImage *fullImage = UIGraphicsGetImageFromCurrentImageContext(); // 结束上下文 UIGraphicsEndImageContext(); // 4.回到主线程显示图片 dispatch_async(dispatch_get_main_queue(), ^{ self.imgView.image = fullImage; }); }); }复制代码
2、分别开启两条线程下载图片,然后再判断图片是否下载成功,最后合并完图片之后回到住线程刷新UI
/// 分别开启两条线程下载图片,然后再判断图片是否下载成功,最后合并完图片之后回到住线程刷新UI
- (void)mergedImages2 {
// 异步下载
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 1.下载第1张
UIImage *image1 = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:ImgUrl3]]];
self.image1 = image1;
[self bindImages]
; }); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // 2.下载第2张 UIImage *image2 = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:ImgUrl4]]]; self.image2 = image2;
[self bindImages]
; }); } - (void)bindImages { if (self.image1 == nil || self.image2 == nil) return; // 3.合并图片 // 开启一个位图上下文 UIGraphicsBeginImageContextWithOptions(self.image1.size, NO, 0.0); // 绘制第1张图片 CGFloat image1W = self.image1.size.width; CGFloat image1H = self.image1.size.height;
[self.image1 drawInRect:CGRectMake(0, 0, image1W, image1H)]
; // 绘制第2张图片 CGFloat image2W = self.image2.size.width; CGFloat image2H = self.image2.size.height * 0.5; CGFloat image2Y = image1H * 0.5;
[self.image2 drawInRect:CGRectMake(0, image2Y, image2W, image2H)]
; // 得到上下文中的图片 UIImage *fullImage = UIGraphicsGetImageFromCurrentImageContext(); // 结束上下文 UIGraphicsEndImageContext(); // 4.回到主线程显示图片 dispatch_async(dispatch_get_main_queue(), ^{ self.imgView.image = fullImage; }); }复制代码
3、利用队列组方式,轻松实现
/// 利用队列组方式,轻松实现
- (void)queueGroupImplementation {
// 1.队列组
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 2.下载图片1
__block UIImage *image1 = nil;
dispatch_group_async(group, queue, ^{
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:ImgUrl5]]];
image1 = image;
});
// 3.下载图片2
__block UIImage *image2 = nil;
dispatch_group_async(group, queue, ^{
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:ImgUrl6]]];
image2 = image;
});
// 4.合并图片 (保证执行完组里面的所有任务之后,再执行notify函数里面的block)
dispatch_group_notify(group, queue, ^{
// 开启一个位图上下文
UIGraphicsBeginImageContextWithOptions(image1.size, NO, 0.0);
// 绘制第1张图片
CGFloat image1W = image1.size.width;
CGFloat image1H = image1.size.height;
[image1 drawInRect:CGRectMake(0, 0, image1W, image1H)]
; // 绘制第2张图片 CGFloat image2W = image2.size.width; CGFloat image2H = image2.size.height * 0.5; CGFloat image2Y = image1H * 0.5;
[image2 drawInRect:CGRectMake(0, image2Y, image2W, image2H)]
; // 得到上下文中的图片 UIImage *fullImage = UIGraphicsGetImageFromCurrentImageContext(); // 结束上下文 UIGraphicsEndImageContext(); // 5.回到主线程显示图片 dispatch_async(dispatch_get_main_queue(), ^{ self.imgView.image = fullImage; }); }); }