这篇文章将演示GCD三个特性的使用:
1.延迟执行
2.一次性执行
3.调度组
- 延迟执行
示例代码:
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
NSLog(@"begin");
// 延迟执行
/*
参数1: <#delayInSeconds#> --> 延迟多少时间执行
参数2: dispatch_queue_t --> 执行操作的队列
参数3: dispatch_block_t --> 执行的任务
异步执行,并不会卡死主线程
*/
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"%s",__func__);
});
NSLog(@"end");
}
@end
LOG信息:
2016-08-21 13:39:05.720 延迟执行[23451:3109328] begin
2016-08-21 13:39:05.721 延迟执行[23451:3109328] end
2016-08-21 13:39:10.722 延迟执行[23451:3109328] __41-[ViewController touchesBegan:withEvent:]_block_invoke
- 一次性执行
示例代码:
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
// 一次性执行 (线程安全,只执行一次)
for (int i = 0; i < 10; i ++) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"%s",__func__);
});
}
}
@end
因为这种一次性执行的特性,常常被使用在单例设计模式中,并且性能突出
http://www.jianshu.com/p/1da234f4b551
- 调度组
有时候需要在多个异步任务都执行完成之后继续做某些事情,比如下载歌曲,等所有的歌曲都下载完毕之后,转到主线程提示用户,通过GCD的调度组功能即可实现这种需求
参数1:<#dispatch_group_t group#> -> 调度组
参数2:<#dispatch_queue_t queue#> -> 队列
参数3:<#^(void)block#> -> 任务
dispatch_group_async(<#dispatch_group_t group#>, <#dispatch_queue_t queue#>, <#^(void)block#>)
示例代码:
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
// 调度组使用
// 需求: 任务1&任务2&任务3 --> 全部都完成后(不限制执行顺序),提示完成
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
// 1.需要执行的任务
dispatch_block_t task1 = ^{
[NSThread sleepForTimeInterval:3];
NSLog(@"操作1");
};
dispatch_block_t task2 = ^{
[NSThread sleepForTimeInterval:5];
NSLog(@"操作2");
};
dispatch_block_t task3 = ^{
[NSThread sleepForTimeInterval:1];
NSLog(@"操作3");
};
// 2.创建调度组
dispatch_group_t group = dispatch_group_create();
// 3.添加到调度组中
/* dispatch_group_async(<#dispatch_group_t group#>, <#dispatch_queue_t queue#>, <#^(void)block#>)
参数1:<#dispatch_group_t group#> -> 调度组
参数2:<#dispatch_queue_t queue#> -> 队列(处理任务执行的队列)
参数3:<#^(void)block#> -> 任务
*/
dispatch_group_async(group, dispatch_get_global_queue(0, 0), task1);
dispatch_group_async(group, dispatch_get_global_queue(0, 0), task2);
dispatch_group_async(group, dispatch_get_global_queue(0, 0), task3);
// 4.调度组内的任务执行完毕后回到主线程通知
/* dispatch_group_notify(<#dispatch_group_t group#>, <#dispatch_queue_t queue#>, <#^(void)block#>)
参数1:<#dispatch_group_t group#> -> 调度组
参数2:<#dispatch_queue_t queue#> -> 队列(参数3内的代码执行队列)
参数3:<#^(void)block#> -> 任务
*/
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"执行完毕");
});
}
@end
上述调度组的示例代码中,通过创建任务,调度组,在通过调度组异步处理任务时,将任务自动放入调度组中执行
调度组的原理:
- (void)demo{
// 创建调度组
dispatch_group_t group = dispatch_group_create();
// 相当于任务1
// 将后面的代码放入调度组中执行
dispatch_group_enter(group);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[NSThread sleepForTimeInterval:3];
NSLog(@"操作1");
//任务执行完毕后离开调度组
dispatch_group_leave(group);
});
// 相当于任务2
dispatch_group_enter(group);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[NSThread sleepForTimeInterval:3];
dispatch_group_leave(group);
NSLog(@"操作2");
});
// 相当于任务3
dispatch_group_enter(group);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[NSThread sleepForTimeInterval:3];
NSLog(@"操作3");
dispatch_group_leave(group);
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"任务执行完毕");
});
}
调度组的实现过程:
1.通过dispatch_group_enter(group);手动让后面的代码进入调度组
2.当任务执行完毕后,通过dispatch_group_leave(group);离开调度组
3.当所有任务执行完毕后,调用dispatch_group_notify做最后的处理
dispatch_group_notify(<#dispatch_group_t group#>, <#dispatch_queue_t queue#>, <#^(void)block#>)