使用GCD处理几个线程之间的依赖关系。
2017-10-31 21:16
429 查看
有时候我们在开发过程中,会有这样的需求,a任务开始执行的前提是b任务执行完成,c任务开始执行需要等a、b两个异步任务完成,即a依赖于b,c又依赖a,这种需求我们可以使用的GCD来处理。
//创建分组
dispatch_group_t group =dispatch_group_create();
//创建队列
dispatch_queue_t queue =dispatch_queue_create("queue",DISPATCH_QUEUE_CONCURRENT);
//往分组中添加任务
dispatch_group_async(group, queue, ^{
[NSThreadsleepForTimeInterval:2];//模拟耗时操作
NSLog(@"11111 %@", [NSThreadcurrentThread]);
});
//往分组中添加任务
dispatch_group_async(group, queue, ^{
[NSThreadsleepForTimeInterval:1];//模拟耗时操作
NSLog(@"2222 %@", [NSThreadcurrentThread]);
});
//分组中任务完成以后通知该block执行
dispatch_group_notify(group, queue, ^{
NSLog(@"完成
%@", [NSThreadcurrentThread]);
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"通知主线程刷新UI
%@", [NSThreadcurrentThread]);
});
});
执行结果:
2017-10-24 11:33:40.426 iOSTest[34497:828682] 2222 0x600000260080>{number = 3, name =
(null)}
2017-10-24 11:33:41.426 iOSTest[34497:828660] 11111 0x608000261d80>{number = 4, name =
(null)}
2017-10-2411:33:41.427 iOSTest[34497:828660]
完成 0x608000261d80>{number = 4, name =
(null)}
2017-10-2411:33:41.427 iOSTest[34497:828365]
通知主线程刷新UI 0x60800007b980>{number = 1, name =
main}
这样我们使用group可以实现几个任务之间的依赖关系。
然而有时我们的任务一层一层的嵌套了多个Block,这个时候,就应该使用如下代码方式:
//创建分组
dispatch_group_t group =dispatch_group_create();
//创建队列
dispatch_queue_t queue =dispatch_queue_create("queue",DISPATCH_QUEUE_CONCURRENT);
//往分组中添加任务
dispatch_group_async(group, queue, ^{
void (^task)(void) = ^{
[NSThreadsleepForTimeInterval:2];//模拟耗时操作
NSLog(@"11111 %@", [NSThreadcurrentThread]);
};
dispatch_async(dispatch_get_global_queue(0,0),
task);
NSLog(@"11111---- %@", [NSThreadcurrentThread]);
});
//往分组中添加任务
dispatch_group_async(group, queue, ^{
void (^task)(void) = ^ {
[NSThreadsleepForTimeInterval:1];//模拟耗时操作
NSLog(@"2222 %@", [NSThreadcurrentThread]);
};
dispatch_async(dispatch_get_global_queue(0,0),
task);
NSLog(@"2222------- %@", [NSThreadcurrentThread]);
});
//分组中任务完成以后通知该block执行
dispatch_group_notify(group, queue, ^{
NSLog(@"完成
%@", [NSThreadcurrentThread]);
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"通知主线程刷新UI
%@", [NSThreadcurrentThread]);
});
});
执行结果:
2017-10-24 11:44:06.447 iOSTest[34981:881063] 2222-------
{number = 4, name = (null)}
2017-10-2411:44:06.447 iOSTest[34981:881046] 11111----
{number = 3, name = (null)}
2017-10-24 11:44:06.448iOSTest[34981:881046]
完成 0x600000071f40>{number = 3, name =
(null)}
2017-10-24 11:44:06.450iOSTest[34981:880987]
通知主线程刷新UI 0x60000006c340>{number = 1, name =
main}
2017-10-2411:44:07.450 iOSTest[34981:881064] 2222 0x6000000708c0>{number = 5, name =
(null)}
2017-10-2411:44:08.452 iOSTest[34981:881049] 11111 0x61000006d5c0>{number = 6, name =
(null)}
根据执行结果可以看出,当主线程执行的时候,然而其他两个任务中并没有真正的完成,因为另外两个任务中嵌套了子任务,那问题来了,其他两个任务还没有完成就执行主线程,但是我们需要的是其他两个任务完成才需要执行主线程,别急,group给我们提供了dispatch_group_enter()与dispatch_group_leave()方法来组合运用,值得注意的是,这两个方法一定需要成对使用,要不然有时间又出现一些莫名其妙的bug问题。
代码如下:
//创建分组
dispatch_group_t group =dispatch_group_create();
//创建队列
dispatch_queue_t queue =dispatch_queue_create("queue",DISPATCH_QUEUE_CONCURRENT);
//往分组中添加任务
dispatch_group_enter(group);
dispatch_async(queue, ^{
void (^task)(void) = ^{
[NSThreadsleepForTimeInterval:2];//模拟耗时操作
NSLog(@"11111 %@", [NSThreadcurrentThread]);
dispatch_group_leave(group);
};
dispatch_async(dispatch_get_global_queue(0,0),
task);
NSLog(@"11111---- %@", [NSThreadcurrentThread]);
});
//往分组中添加任务
dispatch_group_enter(group);
dispatch_async(queue, ^{
void (^task)(void) = ^ {
[NSThreadsleepForTimeInterval:1];//模拟耗时操作
NSLog(@"2222 %@", [NSThreadcurrentThread]);
dispatch_group_leave(group);
};
dispatch_async(dispatch_get_global_queue(0,0),
task);
NSLog(@"2222------- %@", [NSThreadcurrentThread]);
});
//分组中任务完成以后通知该block执行
dispatch_group_notify(group, queue, ^{
NSLog(@"完成
%@", [NSThreadcurrentThread]);
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"通知主线程刷新UI
%@", [NSThreadcurrentThread]);
});
});
执行结果如下:
2017-10-24 11:48:05.641 iOSTest[35128:902591] 11111----
{number = 3, name = (null)}
2017-10-2411:48:05.641 iOSTest[35128:902608] 2222-------
{number = 4, name = (null)}
2017-10-24 11:48:06.644iOSTest[35128:902609] 2222 0x60000006cb00>{number = 5, name =
(null)}
2017-10-24 11:48:07.644iOSTest[35128:902593] 11111 0x6080000721c0>{number = 6, name =
(null)}
2017-10-24 11:48:07.644iOSTest[35128:902593]
完成 0x6080000721c0>{number = 6, name =
(null)}
2017-10-24 11:48:07.645iOSTest[35128:902524]
通知主线程刷新UI 0x61000006e280>{number = 1, name =
main}
这样我们想要的得到的结果就实现了。
//创建分组
dispatch_group_t group =dispatch_group_create();
//创建队列
dispatch_queue_t queue =dispatch_queue_create("queue",DISPATCH_QUEUE_CONCURRENT);
//往分组中添加任务
dispatch_group_async(group, queue, ^{
[NSThreadsleepForTimeInterval:2];//模拟耗时操作
NSLog(@"11111 %@", [NSThreadcurrentThread]);
});
//往分组中添加任务
dispatch_group_async(group, queue, ^{
[NSThreadsleepForTimeInterval:1];//模拟耗时操作
NSLog(@"2222 %@", [NSThreadcurrentThread]);
});
//分组中任务完成以后通知该block执行
dispatch_group_notify(group, queue, ^{
NSLog(@"完成
%@", [NSThreadcurrentThread]);
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"通知主线程刷新UI
%@", [NSThreadcurrentThread]);
});
});
执行结果:
2017-10-24 11:33:40.426 iOSTest[34497:828682] 2222 0x600000260080>{number = 3, name =
(null)}
2017-10-24 11:33:41.426 iOSTest[34497:828660] 11111 0x608000261d80>{number = 4, name =
(null)}
2017-10-2411:33:41.427 iOSTest[34497:828660]
完成 0x608000261d80>{number = 4, name =
(null)}
2017-10-2411:33:41.427 iOSTest[34497:828365]
通知主线程刷新UI 0x60800007b980>{number = 1, name =
main}
这样我们使用group可以实现几个任务之间的依赖关系。
然而有时我们的任务一层一层的嵌套了多个Block,这个时候,就应该使用如下代码方式:
//创建分组
dispatch_group_t group =dispatch_group_create();
//创建队列
dispatch_queue_t queue =dispatch_queue_create("queue",DISPATCH_QUEUE_CONCURRENT);
//往分组中添加任务
dispatch_group_async(group, queue, ^{
void (^task)(void) = ^{
[NSThreadsleepForTimeInterval:2];//模拟耗时操作
NSLog(@"11111 %@", [NSThreadcurrentThread]);
};
dispatch_async(dispatch_get_global_queue(0,0),
task);
NSLog(@"11111---- %@", [NSThreadcurrentThread]);
});
//往分组中添加任务
dispatch_group_async(group, queue, ^{
void (^task)(void) = ^ {
[NSThreadsleepForTimeInterval:1];//模拟耗时操作
NSLog(@"2222 %@", [NSThreadcurrentThread]);
};
dispatch_async(dispatch_get_global_queue(0,0),
task);
NSLog(@"2222------- %@", [NSThreadcurrentThread]);
});
//分组中任务完成以后通知该block执行
dispatch_group_notify(group, queue, ^{
NSLog(@"完成
%@", [NSThreadcurrentThread]);
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"通知主线程刷新UI
%@", [NSThreadcurrentThread]);
});
});
执行结果:
2017-10-24 11:44:06.447 iOSTest[34981:881063] 2222-------
{number = 4, name = (null)}
2017-10-2411:44:06.447 iOSTest[34981:881046] 11111----
{number = 3, name = (null)}
2017-10-24 11:44:06.448iOSTest[34981:881046]
完成 0x600000071f40>{number = 3, name =
(null)}
2017-10-24 11:44:06.450iOSTest[34981:880987]
通知主线程刷新UI 0x60000006c340>{number = 1, name =
main}
2017-10-2411:44:07.450 iOSTest[34981:881064] 2222 0x6000000708c0>{number = 5, name =
(null)}
2017-10-2411:44:08.452 iOSTest[34981:881049] 11111 0x61000006d5c0>{number = 6, name =
(null)}
根据执行结果可以看出,当主线程执行的时候,然而其他两个任务中并没有真正的完成,因为另外两个任务中嵌套了子任务,那问题来了,其他两个任务还没有完成就执行主线程,但是我们需要的是其他两个任务完成才需要执行主线程,别急,group给我们提供了dispatch_group_enter()与dispatch_group_leave()方法来组合运用,值得注意的是,这两个方法一定需要成对使用,要不然有时间又出现一些莫名其妙的bug问题。
代码如下:
//创建分组
dispatch_group_t group =dispatch_group_create();
//创建队列
dispatch_queue_t queue =dispatch_queue_create("queue",DISPATCH_QUEUE_CONCURRENT);
//往分组中添加任务
dispatch_group_enter(group);
dispatch_async(queue, ^{
void (^task)(void) = ^{
[NSThreadsleepForTimeInterval:2];//模拟耗时操作
NSLog(@"11111 %@", [NSThreadcurrentThread]);
dispatch_group_leave(group);
};
dispatch_async(dispatch_get_global_queue(0,0),
task);
NSLog(@"11111---- %@", [NSThreadcurrentThread]);
});
//往分组中添加任务
dispatch_group_enter(group);
dispatch_async(queue, ^{
void (^task)(void) = ^ {
[NSThreadsleepForTimeInterval:1];//模拟耗时操作
NSLog(@"2222 %@", [NSThreadcurrentThread]);
dispatch_group_leave(group);
};
dispatch_async(dispatch_get_global_queue(0,0),
task);
NSLog(@"2222------- %@", [NSThreadcurrentThread]);
});
//分组中任务完成以后通知该block执行
dispatch_group_notify(group, queue, ^{
NSLog(@"完成
%@", [NSThreadcurrentThread]);
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"通知主线程刷新UI
%@", [NSThreadcurrentThread]);
});
});
执行结果如下:
2017-10-24 11:48:05.641 iOSTest[35128:902591] 11111----
{number = 3, name = (null)}
2017-10-2411:48:05.641 iOSTest[35128:902608] 2222-------
{number = 4, name = (null)}
2017-10-24 11:48:06.644iOSTest[35128:902609] 2222 0x60000006cb00>{number = 5, name =
(null)}
2017-10-24 11:48:07.644iOSTest[35128:902593] 11111 0x6080000721c0>{number = 6, name =
(null)}
2017-10-24 11:48:07.644iOSTest[35128:902593]
完成 0x6080000721c0>{number = 6, name =
(null)}
2017-10-24 11:48:07.645iOSTest[35128:902524]
通知主线程刷新UI 0x61000006e280>{number = 1, name =
main}
这样我们想要的得到的结果就实现了。
相关文章推荐
- iOS-线程之GCD方式---之同步异步和串行队列并行队列之间的关系
- 使用maven命令来分析jar包之间的依赖关系
- 使用GCD来处理后台线程和UI线程的交互
- 【maven之三】使用maven插件来分析jar包之间的依赖关系
- [原创]java WEB学习笔记99:Spring学习---Spring Bean配置:自动装配,配置bean之间的关系(继承/依赖),bean的作用域(singleton,prototype,web环境作用域),使用外部属性文件
- NSOperation之依赖关系和GCD之间的对比
- Perl Email处理几个模块之间的关系
- 第五节:Task构造函数之TaskCreationOptions枚举处理父子线程之间的关系。
- 使用Windows消息队列处理线程之间通信
- 安卓中Rxjava(观察者模式、异步)的简单使用(1) 观察者与被观察者线程之间的关系
- 掌握GCD以及后台永久运行的代码 (使用GCD处理后台线程和UI线程的交互)
- 小心得:处理两个头文件互调,死循环情况(将文件之间的编译依赖关系降至最低)
- 使用GCD处理后台线程和UI线程的交互(转自唐巧的技术博客)
- 10.2 NSOperation/NSOperationQueue:提供了一些在GCD中不容易实现的特性,如:限制最大并发数量,操作之间的依赖关系.
- Android 系列 4.11使用活动线程队列和处理程序在线程之间发送消息
- 使用maven命令来分析jar包之间的依赖关系
- Hadoop使用JobControl设置job之间的依赖关系
- 使用GCD来处理后台线程和UI线程的交互
- 作为项目经理,如何处理好与不同类型客户之间的关系?
- 如何认识使用 PowerDesigner 中的强制和依赖关系