GCD各种队列的执行效果
GCD的2个核心:
任务
队列
– | 并发队列 | 手动创建的串行队列 | 主队列 |
---|---|---|---|
同步(sync) | 不会开启新线程 2. 串行执行任务 | 1.不会开启新线程 2. 串行执行任务 | 没有开启新线程 2. 串行执行任务(容易堵塞) |
异步(async) | 1. 开启新线程 2. 并发执行任务 | 1. 开启新线程 2. 串行执行任务 | 没有开新线程 2. 串行执行任务 |
- 1. 同步异步: 能不能开启线程
1.1 同步: 不能开启新线程,
1.2 异步: 可以开启新的线程
- 2. 串行并行: 任务执行的方式
2.1 串行: 任务一个一个的执行
2.2 并行: 允许多个任务同时执行
注意:
1. 使用sync函数
往当前串行队列
中添加任务, 会卡住当前的队列
2. 只要是同步队列 都不会开启新的线程
3. 只要是异步队列, 并且不再主线程中, 都会开启新的线程
4. 异步函数async 先执行任务(当前的函数执行完) 再开启线程, 所以不会阻塞主线程
dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);
起到栅栏作用, dispatch_barrier_async前的队列先执行, 再执行dispatch_barrier_async队列, 再执行dispatch_barrier_async后面的队列
这个queue不能是dispath_get_global_queue(), 需要自己定义
dispatch_apply(size, queue(异步), block)
快速遍历数组,
创建多个异步队列, 同时完成遍历, 速度比for快
补充:
NSString *path1;
NSString *paht2;
NSFileManager *manager = [NSFileManager defaultManager];
NSArray *subpaths = [manager subpathsAtPath:path1];
disaptch_apply(subpaths.count, dispath_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t index){
//index 顺序不定
NSString *fromPath = [path1 stringByAppendingPathcomponent:subpaths[index]];
NSString *toPath = [path2 stringByAppendingPathcomponent:subpaths[index]]
//剪切
[manager moveItemAtPath:fromPath toPath:toPath error:nil];
})
dispath_group_async()
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 创建一个队列组
dispatch_group_t group = dispatch_group_create();
// 1.下载图片1
dispatch_group_async(group, queue, ^{
});
// 2.下载图片2
dispatch_group_async(group, queue, ^{
});
// 3.将图片1、图片2合成一张新的图片
dispatch_group_notify(group, queue, ^{
// 开启新的图形上下文
UIGraphicsBeginImageContext(CGSizeMake(100, 100));
// 绘制图片
[image1 drawInRect:CGRectMake(0, 0, 50, 100)];
[image2 drawInRect:CGRectMake(50, 0, 50, 100)];
// 取得上下文中的图片
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
// 结束上下文
UIGraphicsEndImageContext();
// 回到主线程显示图片
dispatch_async(dispatch_get_main_queue(), ^{
// 4.将新图片显示出来
self.imageView.image = image;
});
});
dispatch_source_set_timer:GCD计时器
/**
* 两个注意点:
* 1. 强引用dispatch_source_t 对象
* 2. 手动启动定时器dispatch_resume(self.tiemr)
*/
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
/**
* 1. 创建计时器
* @param type source类型
* @param handle 0
* @param mask 0
* @param queue
* @return GCD 定时器
*/
self.tiemr = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
/**
* 2. 设置计时器的各种属性
* @param start 什么时候开始执行第一个任务
* @param interval 时间间隔
GCD的时间参数, 一般是纳秒(1s = 10的9次方纳秒)
*/
// dispatch_time_t start = DISPATCH_TIME_NOW; //立即执行
dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0*NSEC_PER_SEC)); //两秒后执行
uint64_t interval = (int64_t)(1.0 *NSEC_PER_SEC);
dispatch_source_set_timer(self.tiemr, start, interval, 0);
/**
* 3. 设置回调
*/
dispatch_source_set_event_handler(self.tiemr, ^{
//do something for cycle
NSLog(@"--%@--", [NSThread currentThread]);
});
/**
* 4. 启动定时器
*/
dispatch_resume(self.tiemr);
/**
* 5. 取消定时器
*/
// dispatch_cancel(self.tiemr);
// self.tiemr = nil;