iOS多线程__GCD小结
首先我解释一下GCD中常见的语法及其含义
dispatch_async是开启一个异步线程,他的第一个参数是指明队列,第二个参数指明权重,也就是优先级。
dispatch_once是表示这段代码只会执行到一次
dispatch_after表示延时操作
dispatch_queue_create自定义支线程,因为系统只有一个支线程队列(global_queue)
dispatch_group_async 在并行队列中,可以把需要的操作放到最后一个任务执行
dispatch_barrier_async 这是一个有原则的线程,他会看队列中是否有其他需要执行的任务,如果有的话,先让他执行;在他之后的,就必须的等他执行完才能执行
dispatch_apply 一个任务重复执行多次
define DISPATCH_QUEUE_PRIORITY_HIGH 2 优先级高
define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 默认
define DISPATCH_QUEUE_PRIORITY_LOW (-2) 优先级低
还有一个,一般来说系统本身会有3个队列。 global_queue,current_queue,以及main_queue.
想了解GCD的话,还得先了解下编程中的同步,异步,并行这个概念。
同步的概念就是 :老板让十个人去搬砖,按照顺序,甲搬完了乙搬。老板坐在那里不能干别的,一直看着。
异步:十个人都去搬砖,互相不干扰
并行:它是在异步的基础上,提高效率,老板去干别的事情了,喝茶去了。
一般来说,异步和并行是联系在一起的,异步是并行的基础。同步一般都是在主线程(main_queue)完成的。而异步是开启了支线程(global_queue),所以如果用点击按钮的时候,不会造成阻塞,这样就有了并行这一说了。
上面都是关于GCD的介绍,现在我们用例子来依次介绍其用法
1.同步加载图片(会导致主线程阻塞,卡顿)
for (int i = 0 ; i < 10; i++) {
UIImage *img = [self getImgeWith:[urlArr objectForIndex:i]];
[myImgV[i] setImage:img];
}
```
2.异步加载图片,这个也是最常见的用法
for (int i = 0 ; i < 10; i++) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// 处理耗时操作的代码块...
UIImage *img = [self getImgeWith:[urlArr objectForIndex:i]];
//通知主线程刷新
dispatch_async(dispatch_get_main_queue(), ^{
//回调或者说是通知主线程刷新,
[myImgV[i] setImage:img];
});
});
3.dispatch_once在应用的生命周期中只会运行一次,而且线程安全不需要加锁操作,下面是一个简单的单例的创建
+(void)shareUnity
{
static Unity *shared = nil;
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
shared = [[self alloc] init];
//放初始化代码
});
return shared;
}
```
4.dispatch_after带两个参数,一个是时间,一个是指定线程,例子中就是在主线程中40秒过后,会干啥
简单点就这样写
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(40 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//干点啥
});
也可以正式点
double delaySeconds =2.0;
dispatch_time_t popTime=dispatch_time(DISPATCH_TIME_NOW, delaySeconds *NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_global_queue(0, 0), ^{
//干点啥
});
5.dispatch_queue_create自定义一个线程,记得自己要释放掉,毕竟不是亲生的
dispatch_queue_t user_queue=dispatch_queue_create("momoPush", NULL);
dispatch_async(user_queue, ^{
<#code#>
});
dispatch_release(user_queue);
```
6.dispatch_group_async 多线程并发,这样中间的过程会多线程,汇总结果最后才运行
dispatch_group_t group=dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
<#code#>
//并发线程一优先级高
});
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
<#code#>
//并发线程二优先级默认
});
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
<#code#>
//并发线程三优先级
});
dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
<#code#>
//汇总三个结果
});
7.dispatch_barrier_async 前面的几个并发线程怎么去抢着过独木桥,他不管,他只管轮到自己的时候,别的线程都不准走,等他走完,再随便你抢。[我看这个例子就蛮好的](http://blog.csdn.net/wangzitao126/article/details/42225075)
然后我就不写例子了
8.dispathc_apply一般都会和dispatch_async联合使用,用来提高效率。但是如果必须的按照顺序的dosomething的话,可以直接用串行。
dispatch_async(dispatch_get_global_queue(0, 0), ^{
dispatch_apply(100, dispatch_get_global_queue(0, 0), ^(size_t index) {
NSLog(@"%ld",index);
});
NSLog(@"welldone");
});