转自:http://blog.youkuaiyun.com/pre_eminent/article/details/41408715
1、GCD串行队列+异步dispatch
说明:
非常非常非常有用的操作
异步,表示会在主线程之外开新的线程,但由于 队列是串行的,故只开
一个(只开一个)新的线程
当dispatch分派好block之后,主线程立即返回,继续向下执行
串行队列,表示:被分派到此队列的block们,将FIFO有序地一个接一个执行
dispatch_async说明:
立即返回,从不等待,队列决定是serially还是concurrently,block_copy(),block_release()

程序运行结果输出:
可以看到:串行队列+异步方式向队列添加block,
只会新开一个线程,所有被添加的block在新开的线程里,愉快而有序地执行

2、GCD串行队列+同步dispatch (极少使用)
同步表示:不会开新线程,就在主线程上运行
串行表示:所有block一个接一个运行



3、并行队列+异步dispatch(容易失控)
开多条新线程(具体开几个无法控制),block执行没有顺序,程序员无法控制执行顺序


4、并发队列+同步dispatch
关键:因为同步,则不会开新线程,直接使用主线程,
虽然是并发队列,但由于可有一个执行路线,所以会顺序执行


5、发散思维--->串行队列先同步dispatch十个block,再异步dispatch十个block
既然是同步分派:就是在主线程上执行,完毕后,
再异步分派:开新线程,由于队列是串行,故,只会开一条新线程,一个接一个愉快地执行


6、发散思维--->并行队列中,先同步分派10个block,再异步分派10个blcok
只要是同步dispatch,就只会在主线程上运行
再异步分派,就一定会开新线程,由于是并行队列:故会开N条新线程,N数量不可控制,block们的执行顺序也不可控制


7、发散思维--->并行队列中,先异步分派10个block,再同步分派10个blcok
由于是并行,且是异步dispatch:因此会开启多个线程,并且分派完block后,主线程继续向下执行,
只要是同步的dispatch,只会在主线程上执行,因此N条子线程和主线程
穿插执行


8、系统提供的全局队列,供所有的app使用,与【并行队列】的异同如下:
供所有app使用的全局队列
全局队列与 并行队列的3点区别:
1、全局队列不需create、只要get就可以得到
2、全局队列没有名字,因此,调试时,不方便查看
3、全局队列与并行队列的执行效果完全相同


9、主队列 + 同步dispatch 【
阻塞死
】
由于主队列 一直在、随时在等待用户的输入,因此主队列,一直在运行,不会退出;
一旦退出,程序就结束了;
因此,在主队列里面
同步分派
一个block,是永远也不会被执行到的,
该block会将主线程 阻塞住,该block后面的代码也永远不会被执行到

10、主队列 + async分派
在主队列中,无论如何dispatch,只要是加入到主队列的block,
统一由主队列进行安排,顺序执行

















- //
- // ViewController.m
- // GCD
- //
- // Created by xss on 14-11-23.
- // Copyright (c) 2014年 beyond. All rights reserved.
- //
-
- #import "ViewController.h"
-
- @interface ViewController ()
-
- @end
-
- @implementation ViewController
-
- - (void)viewDidLoad {
- [super viewDidLoad];
-
- // [self gcd_serial_async];
-
- // [self gcd_serial_sync];
- // [self gcd_concurrent_async];
- // [self gcd_concurrent_sync];
- // [self gcd_concurrent_sync_async];
- // [self gcd_concurrent_async_sync];
- // [self gcd_serial_sync_async];
- // [self gcd_global_queue];
- // [self gcd_main_queue_sync];
- [self gcd_main_queue_async];
- }
- /*
- 1、主队列 + 异步dispatch (无论如何dispatch,只要加入主队列,都将串行执行,统一由主队列顺序安排)
- */
- - (void)gcd_main_queue_async
- {
-
- dispatch_queue_t mainQueue = dispatch_get_main_queue();
- // 快速向 主队列 里面异步添加10个block
- for (int i = 0; i<10; i++) {
- dispatch_async(mainQueue, ^{
- NSLog(@"\n---------->异步分派:%@--正在执行 主队列 中的第 %d 个block",[NSThread currentThread],i);
- });
- }
-
- }
- /*
- 1、主队列 + 同步dispatch == 永远不被执行
- 因为 主队列 一直有一个block 在监听并处理 UI操作,一直阻塞,不会退出,不会完结
- 因此,同步dispatch的,排在其后面的block永远不会被执行
- */
- - (void)gcd_main_queue_sync
- {
- dispatch_queue_t mainQueue = dispatch_get_main_queue();
- NSLog(@"before");
- dispatch_sync(mainQueue, ^{
- NSLog(@"永远也不会被执行到");
- });
- NSLog(@"after");
- }
- /*
- 供所有app使用的全局队列
- 全局队列 与 并行队列的一点点区别:
- 1、全局队列 不需create、只要get就可以得到
- 2、全局队列 没有名字,因此,调试时,不方便查看
- 3、全局队列 与并行队列的执行效果完全相同
- */
- - (void)gcd_global_queue
- {
- dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
- // 快速向队列里面同步添加10个block
- for (int i = 0; i<10; i++) {
- dispatch_sync(globalQueue, ^{
- NSLog(@"\n---------->同步分派:%@--正在执行全局队列中的第 %d 个block",[NSThread currentThread],i);
- });
- }
- // 快速向队列里面异步添加10个block
- for (int i = 0; i<10; i++) {
- dispatch_async(globalQueue, ^{
- NSLog(@"\n---------->异步分派:%@--正在执行全局队列中的第 %d 个block",[NSThread currentThread],i);
- });
- }
- }
- /*
- 并行队列:先异步分派10个,再同步分派10个
- 总结:穿插执行
- */
- - (void)gcd_concurrent_async_sync
- {
- dispatch_queue_t queue = dispatch_queue_create("并行队列", DISPATCH_QUEUE_CONCURRENT);
- // 快速向队列里面异步添加10个block
- for (int i = 0; i<10; i++) {
- dispatch_async(queue, ^{
- NSLog(@"\n---------->异步分派:%@--正在执行并行队列中的第 %d 个block",[NSThread currentThread],i);
- });
- }
- // 快速向队列里面同步添加10个block
- for (int i = 0; i<10; i++) {
- dispatch_sync(queue, ^{
- NSLog(@"\n---------->同步分派:%@--正在执行并行队列中的第 %d 个block",[NSThread currentThread],i);
- });
- }
-
- }
- /*
- 并行队列:分同步分派10个,再异步分派10个
- */
- - (void)gcd_concurrent_sync_async
- {
- dispatch_queue_t queue = dispatch_queue_create("并行队列", DISPATCH_QUEUE_CONCURRENT);
- // 快速向队列里面同步添加10个block
- for (int i = 0; i<10; i++) {
- dispatch_sync(queue, ^{
- NSLog(@"\n---------->同步分派:%@--正在执行并行队列中的第 %d 个block",[NSThread currentThread],i);
- });
- }
- // 快速向队列里面异步添加10个block
- for (int i = 0; i<10; i++) {
- dispatch_async(queue, ^{
- NSLog(@"\n---------->异步分派:%@--正在执行并行队列中的第 %d 个block",[NSThread currentThread],i);
- });
- }
- }
- /*
- 串行队列:
- 1.先sync分派10个block
- 2.再async分派10个block
- */
- - (void)gcd_serial_sync_async
- {
-
- dispatch_queue_t queue = dispatch_queue_create("串行队列", DISPATCH_QUEUE_SERIAL);
- // 快速向队列里面添加10个block
- for (int i = 0; i<10; i++) {
- // 同步dispatch
- dispatch_sync(queue, ^{
- NSLog(@"---------->同步分派:%@--正在执行串行队列中的第 %d 个block",[NSThread currentThread],i);
- });
- }
- // 快速向队列里面添加10个block
- for (int i = 0; i<10; i++) {
- // 异步dispatch
- dispatch_async(queue, ^{
- NSLog(@"---------->异步分派:%@--正在执行串行队列中的第 %d 个block",[NSThread currentThread],i);
- });
- }
-
- }
- /*
- 并发队列+同步dispatch
- 关键:同步,则不会开新线程,直接使用主线程,
- 虽然是并发队列,但由于 可有一个执行路线,所以会顺序执行
- */
- - (void)gcd_concurrent_sync
- {
- // 参数1:是调试用的,是C字符串,
- // 参数2:A dispatch queue that may invoke blocks concurrently and supports
- // barrier blocks submitted with the dispatch barrier API.
- dispatch_queue_t queue = dispatch_queue_create("并行队列", DISPATCH_QUEUE_CONCURRENT);
- // 快速向队列里面添加10个block
- for (int i = 0; i<10; i++) {
- dispatch_sync(queue, ^{
- NSLog(@"\n---------->同步分派:%@--正在执行并行队列中的第 %d 个block",[NSThread currentThread],i);
- });
- }
-
- }
- /*
- 并发队列+异步dispatch
- 关键:开多条新线程(具体开几个无法控制),block执行没有顺序,程序员无法控制执行顺序
- */
- - (void)gcd_concurrent_async
- {
- // 参数1:是调试用的,是C字符串,
- // 参数2:A dispatch queue that may invoke blocks concurrently and supports
- // barrier blocks submitted with the dispatch barrier API.
- dispatch_queue_t queue = dispatch_queue_create("并行队列", DISPATCH_QUEUE_CONCURRENT);
- // 快速向队列里面添加10个block
- for (int i = 0; i<10; i++) {
- dispatch_async(queue, ^{
- NSLog(@"\n---------->异步分派:%@--正在执行并行队列中的第 %d 个block",[NSThread currentThread],i);
- });
- }
-
- }
- /*
- 串行队列 + 同步dispatch 【极少使用】
- 既然是 同步dispatch,就没有必要开一条新线程,在主线程上 一个接一个block执行
- */
- - (void)gcd_serial_sync
- {
- // 参数1:是调试用的,是C字符串,
- // 参数2:A dispatch queue that invokes blocks serially in FIFO order.
- dispatch_queue_t queue = dispatch_queue_create("串行队列", DISPATCH_QUEUE_SERIAL);
- // 快速向队列里面添加
- for (int i = 0; i<10; i++) {
- dispatch_sync(queue, ^{
- NSLog(@"\n---------->线程:%@--正在执行串行队列中的第 %d 个block",[NSThread currentThread],i);
- });
- }
-
- }
-
-
-
-
- /* 1、串行队列里面的异步任务
- 这个非常有用,举例如下:
- 一个串行的队列里,先执行 下载图片的block
- 然后再执行滤镜操作(如 红眼、高光、羽化等blcok)
- 最后再执行保存block
- */
- - (void)gcd_serial_async
- {
- // 参数1:是调试用的,是C字符串,
- // 参数2:A dispatch queue that invokes blocks serially in FIFO order.
- dispatch_queue_t queue = dispatch_queue_create("串行队列", DISPATCH_QUEUE_SERIAL);
- // 快速向队列里面添加
- for (int i = 0; i<10; i++) {
- // Submits a block for asynchronous execution on a dispatch queue.
- // Calls to dispatch_async() always return immediately after the block has
- // been submitted, and never wait for the block to be invoked.
- dispatch_async(queue, ^{
- NSLog(@"\n---------->线程:%@--正在执行串行队列中的第 %d 个block",[NSThread currentThread],i);
- });
- }
-
- }
-
-
- @end
串行队列: 同步里面 嵌套了同步,结果是:【永远也不会执行】
因为:理论上 是在主线程 执行完 第一个block,再执行 被添加到queue里面的第2个block,但是:由于 第1个block没执行完,是不会执行 后来添加到queue里面的第2个block,因此阻塞住了,第2个被添加到queue里面的block永远不会被执行

开多条新线程(具体开几个无法控制),block执行没有顺序,程序员无法控制执行顺序
关键:因为同步,则不会开新线程,直接使用主线程,
虽然是并发队列,但由于可有一个执行路线,所以会顺序执行
供所有app使用的全局队列
全局队列与 并行队列的3点区别:
1、全局队列不需create、只要get就可以得到
2、全局队列没有名字,因此,调试时,不方便查看
3、全局队列与并行队列的执行效果完全相同
- //
- // ViewController.m
- // GCD
- //
- // Created by xss on 14-11-23.
- // Copyright (c) 2014年 beyond. All rights reserved.
- //
- #import "ViewController.h"
- @interface ViewController ()
- @end
- @implementation ViewController
- - (void)viewDidLoad {
- [super viewDidLoad];
- // [self gcd_serial_async];
- // [self gcd_serial_sync];
- // [self gcd_concurrent_async];
- // [self gcd_concurrent_sync];
- // [self gcd_concurrent_sync_async];
- // [self gcd_concurrent_async_sync];
- // [self gcd_serial_sync_async];
- // [self gcd_global_queue];
- // [self gcd_main_queue_sync];
- [self gcd_main_queue_async];
- }
- /*
- 1、主队列 + 异步dispatch (无论如何dispatch,只要加入主队列,都将串行执行,统一由主队列顺序安排)
- */
- - (void)gcd_main_queue_async
- {
- dispatch_queue_t mainQueue = dispatch_get_main_queue();
- // 快速向 主队列 里面异步添加10个block
- for (int i = 0; i<10; i++) {
- dispatch_async(mainQueue, ^{
- NSLog(@"\n---------->异步分派:%@--正在执行 主队列 中的第 %d 个block",[NSThread currentThread],i);
- });
- }
- }
- /*
- 1、主队列 + 同步dispatch == 永远不被执行
- 因为 主队列 一直有一个block 在监听并处理 UI操作,一直阻塞,不会退出,不会完结
- 因此,同步dispatch的,排在其后面的block永远不会被执行
- */
- - (void)gcd_main_queue_sync
- {
- dispatch_queue_t mainQueue = dispatch_get_main_queue();
- NSLog(@"before");
- dispatch_sync(mainQueue, ^{
- NSLog(@"永远也不会被执行到");
- });
- NSLog(@"after");
- }
- /*
- 供所有app使用的全局队列
- 全局队列 与 并行队列的一点点区别:
- 1、全局队列 不需create、只要get就可以得到
- 2、全局队列 没有名字,因此,调试时,不方便查看
- 3、全局队列 与并行队列的执行效果完全相同
- */
- - (void)gcd_global_queue
- {
- dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
- // 快速向队列里面同步添加10个block
- for (int i = 0; i<10; i++) {
- dispatch_sync(globalQueue, ^{
- NSLog(@"\n---------->同步分派:%@--正在执行全局队列中的第 %d 个block",[NSThread currentThread],i);
- });
- }
- // 快速向队列里面异步添加10个block
- for (int i = 0; i<10; i++) {
- dispatch_async(globalQueue, ^{
- NSLog(@"\n---------->异步分派:%@--正在执行全局队列中的第 %d 个block",[NSThread currentThread],i);
- });
- }
- }
- /*
- 并行队列:先异步分派10个,再同步分派10个
- 总结:穿插执行
- */
- - (void)gcd_concurrent_async_sync
- {
- dispatch_queue_t queue = dispatch_queue_create("并行队列", DISPATCH_QUEUE_CONCURRENT);
- // 快速向队列里面异步添加10个block
- for (int i = 0; i<10; i++) {
- dispatch_async(queue, ^{
- NSLog(@"\n---------->异步分派:%@--正在执行并行队列中的第 %d 个block",[NSThread currentThread],i);
- });
- }
- // 快速向队列里面同步添加10个block
- for (int i = 0; i<10; i++) {
- dispatch_sync(queue, ^{
- NSLog(@"\n---------->同步分派:%@--正在执行并行队列中的第 %d 个block",[NSThread currentThread],i);
- });
- }
- }
- /*
- 并行队列:分同步分派10个,再异步分派10个
- */
- - (void)gcd_concurrent_sync_async
- {
- dispatch_queue_t queue = dispatch_queue_create("并行队列", DISPATCH_QUEUE_CONCURRENT);
- // 快速向队列里面同步添加10个block
- for (int i = 0; i<10; i++) {
- dispatch_sync(queue, ^{
- NSLog(@"\n---------->同步分派:%@--正在执行并行队列中的第 %d 个block",[NSThread currentThread],i);
- });
- }
- // 快速向队列里面异步添加10个block
- for (int i = 0; i<10; i++) {
- dispatch_async(queue, ^{
- NSLog(@"\n---------->异步分派:%@--正在执行并行队列中的第 %d 个block",[NSThread currentThread],i);
- });
- }
- }
- /*
- 串行队列:
- 1.先sync分派10个block
- 2.再async分派10个block
- */
- - (void)gcd_serial_sync_async
- {
- dispatch_queue_t queue = dispatch_queue_create("串行队列", DISPATCH_QUEUE_SERIAL);
- // 快速向队列里面添加10个block
- for (int i = 0; i<10; i++) {
- // 同步dispatch
- dispatch_sync(queue, ^{
- NSLog(@"---------->同步分派:%@--正在执行串行队列中的第 %d 个block",[NSThread currentThread],i);
- });
- }
- // 快速向队列里面添加10个block
- for (int i = 0; i<10; i++) {
- // 异步dispatch
- dispatch_async(queue, ^{
- NSLog(@"---------->异步分派:%@--正在执行串行队列中的第 %d 个block",[NSThread currentThread],i);
- });
- }
- }
- /*
- 并发队列+同步dispatch
- 关键:同步,则不会开新线程,直接使用主线程,
- 虽然是并发队列,但由于 可有一个执行路线,所以会顺序执行
- */
- - (void)gcd_concurrent_sync
- {
- // 参数1:是调试用的,是C字符串,
- // 参数2:A dispatch queue that may invoke blocks concurrently and supports
- // barrier blocks submitted with the dispatch barrier API.
- dispatch_queue_t queue = dispatch_queue_create("并行队列", DISPATCH_QUEUE_CONCURRENT);
- // 快速向队列里面添加10个block
- for (int i = 0; i<10; i++) {
- dispatch_sync(queue, ^{
- NSLog(@"\n---------->同步分派:%@--正在执行并行队列中的第 %d 个block",[NSThread currentThread],i);
- });
- }
- }
- /*
- 并发队列+异步dispatch
- 关键:开多条新线程(具体开几个无法控制),block执行没有顺序,程序员无法控制执行顺序
- */
- - (void)gcd_concurrent_async
- {
- // 参数1:是调试用的,是C字符串,
- // 参数2:A dispatch queue that may invoke blocks concurrently and supports
- // barrier blocks submitted with the dispatch barrier API.
- dispatch_queue_t queue = dispatch_queue_create("并行队列", DISPATCH_QUEUE_CONCURRENT);
- // 快速向队列里面添加10个block
- for (int i = 0; i<10; i++) {
- dispatch_async(queue, ^{
- NSLog(@"\n---------->异步分派:%@--正在执行并行队列中的第 %d 个block",[NSThread currentThread],i);
- });
- }
- }
- /*
- 串行队列 + 同步dispatch 【极少使用】
- 既然是 同步dispatch,就没有必要开一条新线程,在主线程上 一个接一个block执行
- */
- - (void)gcd_serial_sync
- {
- // 参数1:是调试用的,是C字符串,
- // 参数2:A dispatch queue that invokes blocks serially in FIFO order.
- dispatch_queue_t queue = dispatch_queue_create("串行队列", DISPATCH_QUEUE_SERIAL);
- // 快速向队列里面添加
- for (int i = 0; i<10; i++) {
- dispatch_sync(queue, ^{
- NSLog(@"\n---------->线程:%@--正在执行串行队列中的第 %d 个block",[NSThread currentThread],i);
- });
- }
- }
- /* 1、串行队列里面的异步任务
- 这个非常有用,举例如下:
- 一个串行的队列里,先执行 下载图片的block
- 然后再执行滤镜操作(如 红眼、高光、羽化等blcok)
- 最后再执行保存block
- */
- - (void)gcd_serial_async
- {
- // 参数1:是调试用的,是C字符串,
- // 参数2:A dispatch queue that invokes blocks serially in FIFO order.
- dispatch_queue_t queue = dispatch_queue_create("串行队列", DISPATCH_QUEUE_SERIAL);
- // 快速向队列里面添加
- for (int i = 0; i<10; i++) {
- // Submits a block for asynchronous execution on a dispatch queue.
- // Calls to dispatch_async() always return immediately after the block has
- // been submitted, and never wait for the block to be invoked.
- dispatch_async(queue, ^{
- NSLog(@"\n---------->线程:%@--正在执行串行队列中的第 %d 个block",[NSThread currentThread],i);
- });
- }
- }
- @end
串行队列: 同步里面 嵌套了同步,结果是:【永远也不会执行】
因为:理论上 是在主线程 执行完 第一个block,再执行 被添加到queue里面的第2个block,但是:由于 第1个block没执行完,是不会执行 后来添加到queue里面的第2个block,因此阻塞住了,第2个被添加到queue里面的block永远不会被执行