IOS开发入门之iOS多线程:多线程GCD的详情学习
凌雪 2018-10-10 来源 :网络 阅读 889 评论 0

摘要:本文将带你了解IOS开发入门iOS多线程:多线程GCD的详情学习,希望本文对大家学IOS有所帮助。

本文将带你了解IOS开发入门iOS多线程:多线程GCD的详情学习,希望本文对大家学IOS有所帮助。


       

1.   GCD简介


什么是GCD呢?我们先来看看百度百科的解释简单了解下概念

引自百度百科
Grand   Central Dispatch (GCD) 是Apple开发的一个多核编程的较新的解决方法。它主要用于优化应用程序以支持多核处理器以及其他对称多处理系统。它是一个在线程池模式的基础上执行的并行任务。在Mac OS X   10.6雪豹中首次推出,也可在IOS   4及以上版本使用。

为什么要用GCD呢?

因为GCD有很多好处啊,具体如下:

GCD可用于多核的并行运算   GCD会自动利用更多的CPU内核(比如双核、四核) GCD会自动管理线程的生命周期(创建线程、调度任务、销毁线程)   程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码  

既然GCD有这么多的好处,那么下面我们就来系统的学习一下GCD的使用方法。

2.   任务和队列

学习GCD之前,先来了解GCD中两个核心概念:任务和队列。

任务:就是执行操作的意思,换句话说就是你在线程中执行的那段代码。在GCD中是放在block中的。执行任务有两种方式:同步执行和异步执行。两者的主要区别是:是否具备开启新线程的能力。

同步执行(sync):只能在当前线程中执行任务,不具备开启新线程的能力   异步执行(async):可以在新的线程中执行任务,具备开启新线程的能力

队列:这里的队列指任务队列,即用来存放任务的队列。队列是一种特殊的线性表,采用FIFO(先进先出)的原则,即新任务总是被插入到队列的末尾,而读取任务的时候总是从队列的头部开始读取。每读取一个任务,则从队列中释放一个任务。在GCD中有两种队列:串行队列和并行队列。

并行队列(Concurrent   Dispatch   Queue):可以让多个任务并行(同时)执行(自动开启多个线程同时执行任务)
并行功能只有在异步(dispatch_async)函数下才有效   串行队列(Serial Dispatch Queue):让任务一个接着一个地执行(一个任务执行完毕后,再执行下一个任务)  

3.   GCD的使用步骤

GCD的使用步骤其实很简单,只有两步。
1.   创建一个队列(串行队列或并行队列)
2.   将任务添加到队列中,然后系统就会根据任务类型执行任务(同步执行或异步执行)

下边来看看队列的创建方法和任务的创建方法。

1.   队列的创建方法

可以使用dispatch_queue_create来创建对象,需要传入两个参数,第一个参数表示队列的唯一标识符,用于DEBUG,可为空;第二个参数用来识别是串行队列还是并行队列。DISPATCH_QUEUE_SERIAL表示串行队列,DISPATCH_QUEUE_CONCURRENT表示并行队列。  


   

<code><code><code><code>//   串行队列的创建方法

dispatch_queue_t   queue= dispatch_queue_create("test.queue", DISPATCH_QUEUE_SERIAL);

// 并行队列的创建方法

dispatch_queue_t queue=   dispatch_queue_create("test.queue",   DISPATCH_QUEUE_CONCURRENT);</code></code></code></code>

   

对于并行队列,还可以使用dispatch_get_global_queue来创建全局并行队列。GCD默认提供了全局的并行队列,需要传入两个参数。第一个参数表示队列优先级,一般用DISPATCH_QUEUE_PRIORITY_DEFAULT。第二个参数暂时没用,用0即可。  

2.   任务的创建方法


   

<code><code><code><code><code><code><code>// 同步执行任务创建方法

dispatch_sync(queue, ^{

    NSLog(@"%@",[NSThread currentThread]);      //   这里放任务代码

});

//   异步执行任务创建方法

dispatch_async(queue,   ^{

    NSLog(@"%@",[NSThread currentThread]);      //   这里放任务代码

});</code></code></code></code></code></code></code>

   

虽然使用GCD只需两步,但是既然我们有两种队列,两种任务执行方式,那么我们就有了四种不同的组合方式。这四种不同的组合方式是

并行队列   + 同步执行 并行队列 + 异步执行 串行队列 + 同步执行 串行队列 + 异步执行  

实际上,我们还有一种特殊队列是主队列,那样就有六种不同的组合方式了。

主队列   + 同步执行 主队列 + 异步执行  

那么这几种不同组合方式各有什么区别呢,这里为了方便,先上结果,再来讲解。为图省事,直接查看表格结果,然后可以跳过*   4. GCD的基本使用* 了。

并行队列

串行队列

主队列

同步(sync)    没有开启新线程,串行执行任务    没有开启新线程,串行执行任务    

异步(async)    有开启新线程,并行执行任务    有开启新线程(1条),串行执行任务    

下边我们来分别讲讲这几种不同的组合方式的使用方法。

4.   GCD的基本使用

先来讲讲并行队列的两种使用方法。

1.   并行队列 +   同步执行

不会开启新线程,执行完一个任务,再执行下一个任务  



   

<code><code><code><code><code><code><code>-   (void)   syncConcurrent

{

    NSLog(@"syncConcurrent---begin");

 

    dispatch_queue_t queue=   dispatch_queue_create("test.queue", DISPATCH_QUEUE_CONCURRENT);

 

    dispatch_sync(queue,   ^{

        for (int i   = 0; i   < 2; ++i)   {

            NSLog(@"1------%@",[NSThread currentThread]);

        }

    });

    dispatch_sync(queue,   ^{

        for (int i   = 0; i   < 2; ++i)   {

            NSLog(@"2------%@",[NSThread currentThread]);

        }

    });

    dispatch_sync(queue,   ^{

        for (int i   = 0; i < 2; ++i) {

            NSLog(@"3------%@",[NSThread currentThread]);

        }

    });

 

    NSLog(@"syncConcurrent---end");

}</code></code></code></code></code></code></code>

   

输出结果:
2016-09-03   19:22:27.577 GCD[11557:1897538] syncConcurrent—begin
2016-09-03   19:22:27.578 GCD[11557:1897538] 1——{number = 1, name =   main}
2016-09-03 19:22:27.578 GCD[11557:1897538] 1——{number = 1,   name = main}
2016-09-03 19:22:27.578 GCD[11557:1897538] 2——{number   = 1, name = main}
2016-09-03 19:22:27.579 GCD[11557:1897538]   2——{number = 1, name = main}
2016-09-03 19:22:27.579 GCD[11557:1897538]   3——{number = 1, name = main}
2016-09-03 19:22:27.579   GCD[11557:1897538] 3——{number = 1, name = main}
2016-09-03   19:22:27.579 GCD[11557:1897538]   syncConcurrent—end

从并行队列   + 同步执行中可以看到,所有任务都是在主线程中执行的。由于只有一个线程,所以任务只能一个一个执行。   同时我们还可以看到,所有任务都在打印的syncConcurrent---begin和syncConcurrent---end之间,这说明任务是添加到队列中马上执行的。  

2.   并行队列 +   异步执行

可同时开启多线程,任务交替执行  


   

<code><code><code><code><code><code><code><code><code><code>-   (void)   asyncConcurrent

{

    NSLog(@"asyncConcurrent---begin");

 

    dispatch_queue_t queue=   dispatch_queue_create("test.queue", DISPATCH_QUEUE_CONCURRENT);

 

    dispatch_async(queue,   ^{

        for (int i   = 0; i   < 2; ++i)   {

            NSLog(@"1------%@",[NSThread currentThread]);

        }

    });

    dispatch_async(queue,   ^{

        for (int i   = 0; i   < 2; ++i)   {

            NSLog(@"2------%@",[NSThread currentThread]);

        }

    });

    dispatch_async(queue,   ^{

        for (int i   = 0; i   < 2; ++i)   {

            NSLog(@"3------%@",[NSThread currentThread]);

        }

    });

 

    NSLog(@"asyncConcurrent---end");

}

</code></code></code></code></code></code></code></code></code></code>

   

输出结果:
2016-09-03   19:27:31.503 GCD[11595:1901548] asyncConcurrent—begin
2016-09-03   19:27:31.504 GCD[11595:1901548] asyncConcurrent—end
2016-09-03   19:27:31.504 GCD[11595:1901626] 1——{number = 2, name =   (null)}
2016-09-03 19:27:31.504 GCD[11595:1901625] 2——{number = 4,   name = (null)}
2016-09-03 19:27:31.504 GCD[11595:1901855]   3——{number = 3, name = (null)}
2016-09-03 19:27:31.504   GCD[11595:1901626] 1——{number = 2, name = (null)}
2016-09-03   19:27:31.504 GCD[11595:1901625] 2——{number = 4, name =   (null)}
2016-09-03 19:27:31.505 GCD[11595:1901855] 3——{number = 3,   name = (null)}

在并行队列   + 异步执行中可以看出,除了主线程,又开启了3个线程,并且任务是交替着同时执行的。   另一方面可以看出,所有任务是在打印的syncConcurrent---begin和syncConcurrent---end之后才开始执行的。说明任务不是马上执行,而是将所有任务添加到队列之后才开始异步执行。  

接下来再来讲讲串行队列的执行方法。

3.   串行队列 + 同步执行

不会开启新线程,在当前线程执行任务。任务是串行的,执行完一个任务,再执行下一个任务  


   

<code><code><code><code><code><code><code><code><code><code><code><code><code>-   (void)   syncSerial

{

    NSLog(@"syncSerial---begin");

 

    dispatch_queue_t queue =   dispatch_queue_create("test.queue",   DISPATCH_QUEUE_SERIAL);

 

    dispatch_sync(queue,   ^{

        for (int i   = 0; i   < 2; ++i)   {

            NSLog(@"1------%@",[NSThread currentThread]);

        }

    });     

    dispatch_sync(queue,   ^{

        for (int i   = 0; i < 2; ++i) {

            NSLog(@"2------%@",[NSThread currentThread]);

        }

    });

    dispatch_sync(queue,   ^{

        for (int i   = 0; i   < 2; ++i)   {

            NSLog(@"3------%@",[NSThread currentThread]);

        }

    });

 

    NSLog(@"syncSerial---end");

}</code></code></code></code></code></code></code></code></code></code></code></code></code>

   

输出结果为:
2016-09-03   19:29:00.066 GCD[11622:1903904] syncSerial—begin
2016-09-03   19:29:00.067 GCD[11622:1903904] 1——{number = 1, name = main}
2016-09-03   19:29:00.067 GCD[11622:1903904] 1——{number = 1, name =   main}
2016-09-03 19:29:00.067 GCD[11622:1903904] 2——{number = 1,   name = main}
2016-09-03 19:29:00.067 GCD[11622:1903904] 2——{number   = 1, name = main}
2016-09-03 19:29:00.067 GCD[11622:1903904]   3——{number = 1, name = main}
2016-09-03 19:29:00.068   GCD[11622:1903904] 3——{number = 1, name = main}
2016-09-03   19:29:00.068 GCD[11622:1903904]   syncSerial—end

在串行队列   + 同步执行可以看到,所有任务都是在主线程中执行的,并没有开启新的线程。而且由于串行队列,所以按顺序一个一个执行。   同时我们还可以看到,所有任务都在打印的syncConcurrent---begin和syncConcurrent---end之间,这说明任务是添加到队列中马上执行的。  

4.   串行队列 + 异步执行

会开启新线程,但是因为任务是串行的,执行完一个任务,再执行下一个任务  


   

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之IOS频道!


本文由 @凌雪 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程