GCD的简述就不过多强调了(网上一搜一大把!)这篇文章主要是记录和学习GCD并学会简单调用。希望能对大家有所帮助,如果有不对的地方还请指出,多谢大家!
GCD主要分为三种队列和队列组:
The Main queue (主线程队列)
Global queue(全局并发队列)
Custom queue(自定义队列)
Group queue(队列组)
主线程队列
1.获取主线程串行队列
dispatch_queue_t queue = dispatch_get_main_queue();
2.异步请求
NSLog(@"1");
dispatch_async(queue, ^{
NSLog(@"异步操作");
});
NSLog(@"2");
3.输出结果为:
由此可见在主线程输出@"1"和@"2",异步输出@"异步操作"。
4.但是当我们用主线程串行队列的时候,使用同步执行时:
出现线程死锁问题,那么什么是线程死锁呢?
死锁即为:两个或多个线程相互等待,导致一个线程都不进行然后程序卡死。
全局并发队列
1.这种队列主要分为四个优先级:
dispatch_queue_t globalDefault = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_queue_t globalHigh = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_queue_t globalLow = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
dispatch_queue_t globalBackGround = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
虽然分为四个优先级,但是他们直接不是绝对的由高到低且全是并发操作,只是DEFAULT和HIGH的执行顺序要略高于LOW和BACKGROUND。
默认都为DISPATCH_QUEUE_PRIORITY_DEFAULT,而第二个参数也默认传0。
2.实现同步:
NSLog(@"1");
dispatch_queue_t globalDefault = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_sync(globalDefault, ^{
NSLog(@"2");
});
NSLog(@"3");
3.输出:
4.全局并发队列的异步和主线程串行队列的用法基本一致,但是有一点区别就是当全局并发队列大量异步操作的时候会出现一种问题:
4.1 当我们大量异步请求的时候:
NSLog(@"1");
dispatch_queue_t globalDefault = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(globalDefault, ^{
NSLog(@"2");
});
//大量异步请求
...
dispatch_async(globalDefault, ^{
NSLog(@"2");
});
NSLog(@"3");
4.2 输出结果为:
可以看到我们在主线程输出@"1"和@"3"的时候用全局并发队列添加了很多异步请求,这个时候子线程却不等主线程运行完毕就先运行了!
4.3 这和 全局并发队列 不同,主线程串行队列 这种主线程队列是一定要等到主线程运行完毕后在进行异步操作:
NSLog(@"1");
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_async(queue, ^{
NSLog(@"2");
});
...
dispatch_async(queue, ^{
NSLog(@"2");
});
NSLog(@"3");
4.4 输出:
4.5 总结:
因为主线程队列一定是等待主线程运行完再执行block里面的操作。但是主线程中却是同步操作,所以主线程等待主线程队列同步请求,而主线程队列却要等待主线程运行完,出现了两个线程相互等待造成死锁。
自定义队列 Custom queue
1. 自定义队列可以自己设置串行和并行,第一个参数只是一个编辑名称,第二个参数设置自定义队列的串行和并行。
//串行 dispatch_queue_t queueSerial = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);
//并行 dispatch_queue_t queueConcurrent = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
2.1.1 串行队列的同步请求:
NSLog(@"1");
dispatch_queue_t queueSerial = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);
dispatch_sync(queueSerial, ^{
NSLog(@"2");
});
NSLog(@"3");
2.1.2 输出:
注意!串行队列同步请求不能嵌套,这样会导致线程死锁。
2.1.3 串行队列的异步操作是可以嵌套的:
NSLog(@"1");
dispatch_queue_t queueSerial = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);
dispatch_async(queueSerial, ^{
NSLog(@"2");
dispatch_async(queueSerial, ^{
NSLog(@"3");
});
});
NSLog(@"4");
2.1.4 输出:
2.1.5 如果有耗时操作的话,串行队列会按顺序等待前面先完成,会造成界面卡顿:
NSLog(@"1");
dispatch_queue_t queueSerial = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);
dispatch_async(queueSerial, ^{
sleep(1);
NSLog(@"2");
});
dispatch_async(queueSerial, ^{
NSLog(@"3");
});
NSLog(@"4");
2.1.6 输出:
从时间上来看,先输出@"1"和@"4",延时1S之后执行@"2"和@"3",并且@"3"要等待@"2"输出后才能输出。
2.2.1 下面是并联同步,并联同步是可以嵌套的:
NSLog(@"1");
dispatch_queue_t queueConcurrent = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_sync(queueConcurrent, ^{
NSLog(@"2");
dispatch_sync(queueConcurrent, ^{
NSLog(@"3");
});
});
NSLog(@"4");
2.2.2 输出:
2.2.3 并行队列的要是操作不用等待前面线程执行完:
NSLog(@"1");
dispatch_queue_t queueConcurrent = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queueConcurrent, ^{
sleep(1);
NSLog(@"2");
});
dispatch_async(queueConcurrent, ^{
NSLog(@"3");
});
NSLog(@"4");
2.2.4 输出:
并联异步操作先执行主线程@"1"和@"4"操作,之后执行@"2"和@"3"但是由于@"2"是耗时操作,所以@"3"不用等待@"2"执行完在执行。
线程组
1. 创建一个线程组
dispatch_group_t group = dispatch_group_create();
2. 使用线程组
NSLog(@"1");
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_async(group, queue, ^{
sleep(1);
NSLog(@"3");
});
dispatch_group_notify(group, queue, ^{
NSLog(@"线程执行完毕");
});
NSLog(@"2");
3. 输出:
dispatch_group_notify 用于监听线程组是否全部执行完毕,如果执行完毕,执行Block里面的代码。
线程等待时间
1. 声明一个线程时间
dispatch_time_t Time = dispatch_time(DISPATCH_TIME_NOW, 10 * NSEC_PER_SEC);
第一个参数默认是DISPATCH_TIME_NOW从现在开始,第二个参数是时间参数(参数)*NSEC_PER_SEC。
2. 使用时间线程,延时操作:
NSLog(@"1");
dispatch_time_t Time = dispatch_time(DISPATCH_TIME_NOW, 10 * NSEC_PER_SEC);
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_after(Time,queue, ^{
NSLog(@"2");
});
NSLog(@"3");
3. 输出:
这次就写这么多把,初级GCD(一)就写这么多,写的不好请多包涵。
特别感谢 http://www.jianshu.com/p/ae786a4cf3b1 这篇文章。还有好多网上无私的奉献者。
这是本人的第一篇文章,以后还要继续努力。