ios线程第二发: GCD(附录2)

来源:互联网 发布:知乐的全部小说目录 编辑:程序博客网 时间:2024/05/17 06:02

GCD

1.简介:Grand Central Dispatch(牛逼的中枢调度器)

  纯 c 语言,提供了非常强大的函数,是”并发技术”的框架,

2.使用优势:

   苹果公司为多核并行运算提出的解决方案

   GCD 会自动利用更多的 CPU 内核(比如双核,四核)

   GCD 会自动管理线程的生命周期(创建线程,调度任务,销毁线程)

   程序员只需要告诉 GCD 想要执行什么任务,不需要写任何线程管理代码


3.核心概念(将”任务”添加到”队列”,指定任务的执行方式)

   1>任务:执行什么操作

          用Block 封装,预先准备好要执行的代码

 

   2>队列:用来存放任务(GCD 会自动将队列中得任务取出,放到对应的线程中执行,取出的时候遵循队列多的 FIFO 原则,先进先出,后进后出)

     (1)自定义队列

         1>串行队列:一次只调度一个任务,一个任务执行完毕之后,再调度下一个

            (使用 dispatch_queue_create 函数创建串行队列

             dispatch_queue_t queue = dispatch_queue_create("cn.itcast.queue", NULL); // 创建

             dispatch_queue_create(const char *label, // 队列名称 

             dispatch_queue_attr_t attr); // 队列属性,一般用NULL即可

             dispatch_release(queue); // 非ARC需要释放手动创建的队列)


           2>并发队列:

              A.可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)

                 并发功能只有在异步(dispatch_async)函数下才有效

                     调度任务的方式,取决于执行任务的函数

                  开启线程上限由 GCD 底层决定

                  GCD 默认提供了全局的并发队列,不需要手动创建

               B.使用 dispatch_get_global_queue 函数获得全局的并发队列

                   dispatch_queue_t dispatch_get_global_queue(

                   dispatch_queue_priority_t priority, // 队列的优先级

                   unsigned long flags); // 此参数暂时无用,用0即可

                  dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0); // 获得全局并发队列

                C.自定义队列的名称可以协助开发调试以及崩溃报告分析

                D.dispatch_release(queue); // 非ARC需要释放手动创建的队列


         (2)主队列:

                负责在主线程上调度任务,如果主线程上又任务执行,会等待主线程空闲后再调度任务执行

                主要用于线程间的通讯:所有的 UI 更新都在主线程上进行

  

         (3)全局队列: 

              1>dispatch_queue_t queue =dispatch_get_global_queue(0 ,0); // 获得全局队列

                 iOS8 开始使用 QOS(服务质量) 替代了原有的优先级

                 获取全局队列时,直接传递 0,可以实现 iOS 7 & iOS 8 的适配

               2>与并发队列对比:

                  调度任务的方式相同

                  全局队列没有队列名称

                  在 MRC 开发中,全局队列不需要释放   

               3>优先级&服务质量:

                   队列优先级

                   QOS(服务质量)IOS8推出:

      3>执行任务的函数:

          (1)同步(执行完这一句代码,再执行后续的代码就是同步);

            dispatch_sync: 任务被添加到队列之后,会在当前线程被调度,

                                 队列中的任务同步执行完成之后,才会调度后续的任务

                                 任务被添加到队列之后:| 串行队列 :会在当前线程同步执行

                                                                | 并发队列 :会在当前线程同步执行 

                                                                | 主队列:    会造成死锁

                                 利用同步,可以建立任务之前的”依赖”关系 

        (2)异步(不必等待执行完这一句代码,就执行下一句);

            dispatch_async: 异步是多线程的代名词

                                 任务被添加到队列之后:| 串行队列 :会开启新的线程调度任务

                                                                | 并发队列 :会开启新的线程调度任务

                                                                | 主队列:   会等待主线程空闲时调度任务

                                  

4.使用步骤

   定制任务:确定想做的事情

   将任务添加到队列中: 

    GCD 会自动将队列中得任务取出,放到对应的线程中执行

    取出的时候遵循队列多的 FIFO 原则,先进先出,后进后出

5.任务的执行函数

   同步: dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);

     queue:队列

     block: 任务

   异步: dispatch_async(dispatch_queue_t queue,dispatch_block_t block);

    

    同步和异步的区别:

    同步:在当前线程中执行

    异步:在另一条线程中执行

6.队列类型

  并发(并行)队列:(Concurrent Dispatch QUeue)

     1>可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)

     并发功能只有在异步(dispatch_async)函数下才有效

     GCD 默认提供了全局的并发队列,不需要手动创建

     2>使用 dispatch_get_global_queue 函数获得全局的并发队列

        dispatch_queue_t dispatch_get_global_queue(

        dispatch_queue_priority_t priority, // 队列的优先级

        unsigned long flags); // 此参数暂时无用,用0即可

        dispatch_queue_t queue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0); // 获得全局并发队列

      3>全局并发队列的优先级

        #define DISPATCH_QUEUE_PRIORITY_HIGH 2 // 高

        #define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 // 默认(中)

        #define DISPATCH_QUEUE_PRIORITY_LOW (-2)// 低

        #define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN // 后台



  串行队列:(Serial Dispatch Queue)

      让任务一个接着一个执行(一个任务执行完毕之后,再执行下一个)

      获得串行队列(两种方式):

       1>使用 dispatch_queue_create 函数创建串行队列

          dispatch_queue_create(const char *label, // 队列名称 

          dispatch_queue_attr_t attr); // 队列属性,一般用NULL即可

          dispatch_queue_t queue = dispatch_queue_create("cn.itcast.queue", NULL); // 创建

          dispatch_release(queue); // 非ARC需要释放手动创建的队列

        2>使用主队列(跟主线程相关联的队列)

            主队列是GCD自带的一种特殊的串行队列

            放在主队列中的任务,都会放到主线程中执行

            使用dispatch_get_main_queue()获得主队列 :dispatch_queue_t queue = dispatch_get_main_queue();

           

           对比:         

             

7.容易混淆的:同步,异步,并发,串行

   同步和异步决定要不要开启新的线程

      同步:在当前的线程中执行任务,不具备开启新线程的能力

      异步:在新的线程中执行任务,具备开启新线程的能力

   并发和串行决定了任务的执行方式:

      并发:多个任务并发(同时)执行

      串行:一个任务执行完毕之后,再执行下一个任务


0 0