完整详解GCD系列(三)-dispatch_group

原创Blog,转载请注明出处

http://blog.csdn.net/column/details/swift-gcd.html

一、dispatch_group

把一组任务提交到队列中,这些队列可以不相关,然后坚挺这组任务完成的事件。

几个用到的函数

1、dispatch_group_create创建一个调度任务组

func dispatch_group_create() -> dispatch_group_t!

2、dispatch_group_async 把一个任务异步提交到任务组里

func dispatch_group_async(_ group: dispatch_group_t!,
                        _ queue: dispatch_queue_t!,
                        _ block: dispatch_block_t!)

参数: group
提交到的任务组,这个任务组的对象会一直持续到任务组执行完毕

queue
提交到的队列,任务组里不同任务的队列可以不同

block
提交的任务

3、dispatch_group_enter/dispatch_group_leave

func dispatch_group_enter(_ group: dispatch_group_t!)
func dispatch_group_leave(_ group: dispatch_group_t!)

这两个方法显示的讲任务组中的任务未执行完毕的任务数目加减1,这种方式用在不使用dispatch_group_async来提交任务,注意:这两个函数要配合使用,有enter要有leave,这样才能保证功能完整实现。也可以用这对函数来让一个闭包关联多个Group

4、dispatch_group_notify 用来监听任务组事件的执行完毕

func dispatch_group_notify(_ group: dispatch_group_t!,
                         _ queue: dispatch_queue_t!,
                         _ block: dispatch_block_t!)

参数: group监听的任务组

queue 执行完毕的这个闭包所在的队列

block 执行完毕所响应的任务

5、dispatch_group_wait 设置等待时间,在等待时间结束后,如果还没有执行完任务组,则返回。返回0代表执行成功,非0则执行失败

long dispatch_group_wait ( dispatch_group_t group, dispatch_time_t timeout );

二、完整的代码解析,模拟提交三个下载任务

class ViewController: UIViewController{
    override func viewDidLoad(){
        super.viewDidLoad()
        var hwcGroup = dispatch_group_create()//创建group
	var globalQueueDefault = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)//全局队列,这个队列为并行队列
	var userCreateQueue =  dispatch_queue_create("com.test.helloHwc",DISPATCH_QUEUE_SERIAL)//创建一个用户队列,这个队列为串行队列
	downLoadTask1(group: hwcGroup,queue: globalQueueDefault)
	downLoadTask2(group: hwcGroup,queue: userCreateQueue)
	downLoadTask3(group: hwcGroup,queue: userCreateQueue)
	//letresult = dispatch_group_wait(hwcGroup,DISPATCH_TIME_FOREVER)
	dispatch_group_notify(hwcGroup,dispatch_get_main_queue()){
		NSLog("Group tasks are done")
	}
	println("Now viewDidLoad is done")
    }
    func downLoadTask1(#group:dispatch_group_t,queue:dispatch_queue_t){
	dispatch_group_async(group,queue){
		sleep(3)
		NSLog("Task1 is done")
	}
    }
   func downLoadTask2(#group:dispatch_group_t,queue:dispatch_queue_t){
	dispatch_group_async(group,queue){
		sleep(3)
		NSLog("Task2 is done")
	}
    }
   func downLoadTask3(#group:dispatch_group_t,queue:dispatch_queue_t){
	dispatch_group_async(group,queue){
		sleep(3)
		NSLog("Task3 is done")
	}
    }
    override func didReceiveMemoryWarning(){
        super.didReceiveMemoryWarning()
    }
}

可以看到输出为

Now viewDidLoad is done
Task2 is done
Task1 is done
Task3 is done
Group task is done

这里task1提交到全局队列中,task2和task3提交到用户穿件的串行队列中,所以task1和task2同时输出,task3在task2结束两秒后输出。

如果把注释那行取消,会等待一段时间,再返回,读者可以自己去试验下

三、关于如何使用dispatch_group_enter/dispatch_group_leave如何使用

<pre name="code" class="plain">class ViewController: UIViewController{
    override func viewDidLoad(){
        super.viewDidLoad()
        var hwcGroup = dispatch_group_create()//创建group
	var globalQueueDefault = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)//全局队列,这个队列为并行队列
	for index:UInt32 in 1...3{
	     dispatch_group_enter(hwcGroup)//提交了一个任务,任务数目加1
		manualDownLoad(index){
		    println("Task\(index) is done")
			dispatch_group_leave(hwcGroup)//完成一个任务,任务数目减1
		}
	}
	let result = dispatch_group_wait(hwcGroup,DISPATCH_TIME_FOREVER)//等待直到完成
	dispatch_group_notify(hwcGroup,dispatch_get_main_queue()){
		println("Group tasks are done")
	}
	println("Now viewDidLoad is done")
    }
    func manualDownLoad(num:UInt32,block:()->()){
	println("Downloading task\(num)")
	sleep(num)
	block()
    }
    override func didReceiveMemoryWarning(){
        super.didReceiveMemoryWarning()
    }
}

输出

Downloading task1
Task1 is done
Downloading task2
Task2 is done
Downloading task3
Task3 is done
Now viewDidLoad is done
Group is done

可以看到,同步进行了下载,这里的任务是串行的,实际消耗时间9s。当然,也可以把下载的任务提交到异步队列中

class ViewController: UIViewController{
    override func viewDidLoad(){
        super.viewDidLoad()
        var hwcGroup = dispatch_group_create()//创建group
	var globalQueueDefault = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)//全局队列,这个队列为并行队列
	for index:UInt32 in 1...3{
	     dispatch_group_enter(hwcGroup)//提交了一个任务,任务数目加1
		manualDownLoad(index,queue:globalQueueDefault){
		    NSLog("Task\(index) is done")
			dispatch_group_leave(hwcGroup)//完成一个任务,任务数目减1
		}
	}
	dispatch_group_notify(hwcGroup,dispatch_get_main_queue()){
		NSLog("Group tasks are done")
	}
	NSLog("Now viewDidLoad is done")
    }
    func manualDownLoad(num:UInt32,queue:dispatch_queue_t, block:()->()){
	dispatch_async(queue){
	NSLog("Downloading task\(num)")
	sleep(num)
	block()
        }
    }
    override func didReceiveMemoryWarning(){
        super.didReceiveMemoryWarning()
    }
}

这样的话,输出是

Downloading task1
Downloading task2
Downloading task3
Now viewDidLoad is done
Task1 is done
Task2 is done
Task3 is done

由于三个模拟的下载任务是并行的,所以实际消耗时间3s

时间: 2024-08-08 01:01:13

完整详解GCD系列(三)-dispatch_group的相关文章

完整详解GCD系列(一)dispatch_async;dispatch_sync;dispatch_

为什么要写这个系列,因为百度了一下,找了很多都是些片面的Blog,拷贝来拷贝去的,写的也很粗糙. 所以,我要写这个系列,尽量把官网文档中GCD的强大功能完整的表达出来.方便自己,也方便别人,如果发现有问题,欢迎提出 本教程的计划:在完整的看过GCD的官方文档之后,我实在想不出来如何用一篇文章详细完整的写出来如此多的功能.所以,决定开一个专栏来写这个教程.计划8篇文章,分别介绍各种功能,每种功能会附上简单完整的示例代码.最后 的一篇文章会进行总结,总结出GCD的经典使用场景.源代码只提供Swift

完整详解GCD系列(一)dispatch_async;dispatch_sync;dispatch_async_f;dispatch_sync_f

为什么要写这个系列,因为百度了一下,找了很多都是些片面的Blog,拷贝来拷贝去的,写的也很粗糙. 所以,我要写这个系列,尽量把官网文档中GCD的强大功能完整的表达出来.方便自己,也方便别人,如果发现有问题,欢迎提出 本教程的计划:在完整的看过GCD的官方文档之后,我实在想不出来如何用一篇文章详细完整的写出来如此多的功能. 所以,决定开一个专栏来写这个教程.计划8篇文章,分别介绍各种功能,每种功能会附上简单完整的示例代码.最后 的一篇文章会进行总结,总结出GCD的经典使用场景.源代码只提供Swif

完整详解GCD系列(四)dispatch_semaphore(信号量)

原创Blog,转载请注明出处 http://blog.csdn.net/hello_hwc?viewmode=contents 一 何为信号量? 简单来说就是控制访问资源的数量,比如系统有两个资源可以被利用,同时有三个线程要访问,只能允许两个线程访问,第三个应当等待资源被释放后再访问. 注意:再GCD中,只有调度的线程在信号量不足的时候才会进入内核态进行线程阻塞 二 如何使用信号量 三个主要函数 创建一个信号量 func dispatch_semaphore_create(_ value: In

完整详解GCD系列(二)dispatch_after;dispatch_apply;dispatch_once

一.dispatch_after 功能:延迟一段时间把一项任务提交到队列中执行,返回之后就不能取消 常用来在在主队列上延迟执行一项任务 函数原型 [plain] view plaincopy func dispatch_after(_ when: dispatch_time_t, _ queue: dispatch_queue_t!, _ block: dispatch_block_t!) 参数 [plain] view plaincopy when 过了多久执行的时间间隔 queue   提交

「视频直播技术详解」系列之七:直播云 SDK 性能测试模型

?关于直播的技术文章不少,成体系的不多.我们将用七篇文章,更系统化地介绍当下大热的视频直播各环节的关键技术,帮助视频直播创业者们更全面.深入地了解视频直播技术,更好地技术选型. 本系列文章大纲如下: (一)采集 (二)处理 (三)编码和封装 (四)推流和传输 (五)延迟优化 (六)现代播放器原理 (七)SDK 性能测试模型 本篇是<视频直播技术详解>系列的最后一篇直播云 SDK 性能测试模型,SDK 的性能对最终 App 的影响非常大.SDK 版本迭代快速,每次发布前都要进行系统的测试,测试要

iOS学习之UINavigationController详解与使用(三)ToolBar

1.显示Toolbar  在RootViewController.m的- (void)viewDidLoad方法中添加代码,这样Toobar就显示出来了. [cpp] view plaincopyprint? [self.navigationController  setToolbarHidden:NO animated:YES]; [self.navigationController setToolbarHidden:NO animated:YES]; 2.在ToolBar上添加UIBarBu

[转]iOS学习之UINavigationController详解与使用(三)ToolBar

转载地址:http://blog.csdn.net/totogo2010/article/details/7682641 iOS学习之UINavigationController详解与使用(二)页面切换和segmentedController 接上篇,我们接着讲Navigation 的Toolbar. 1.显示Toolbar  在RootViewController.m的- (void)viewDidLoad方法中添加代码,这样Toobar就显示出来了. [cpp] view plaincopy

CocoaPods详解之(三)----制作篇

CocoaPods详解之----制作篇 作者:wangzz 原文地址:http://blog.csdn.net/wzzvictory/article/details/20067595 转载请注明出处 如果觉得文章对你有所帮助,请通过留言或关注微信公众帐号wangzzstrive来支持我,谢谢! 学会使用别人的Pods依赖库以后,你一定对创建自己的依赖库跃跃欲试,今天就来揭开Pods依赖库创建过程的神秘面纱.整个创建过程都以我实现的一个名称为WZMarqueeView跑马灯效果的view为例,步骤

高可用高性能负载均衡软件HAproxy详解指南-第三章:HAproxy实例

第三章:HAproxy实例 对Linux有兴趣的朋友加入QQ群:476794643 在线交流 本文防盗链:http://zhang789.blog.51cto.com 上一篇:第二章:HAproxy配置文件详解以及HAproxy的ACL详解 目录 haproxy案例1:定义独立日志文件 haproxy案例2:haproxy统计页面的输出机制 haproxy案例3:动静分离示例: haproxy案例4:实现web负载 haproxy案例5:负载均衡MySQL服务 由于字体过多分开写的,全系列文章链