代码改变世界

iOS开发系列-GCD

2018-04-15 19:03  iCoderHong  阅读(153)  评论(0编辑  收藏  举报

概述

GCD是苹果公司为多核的并行运算提出的解决方案。全称是Grand Central Dospatch。纯C语言,提供了非常多强大的函数。
GCD自动管理线程的声明周期(创建线程、调度任务、销毁线程)。面向开发者只需要告诉GCD执行的任务。

GCD的核心概念

  • 任务-执行的操作
  • 队列-存放任务

GCD将任务添加进队列中,GCD会自动将队列中的任务取出放到对应的线程执行。任务的取出遵循队列的FIFO原则。

GCD基本使用

在使用GCD首先得创建队列。队列是用来添加任务的。GCD队列主要分两种类型:串行队列并发队列。队列类型决定队列中任务执行方式。
如果是串行队列,队列中的任务执行时按顺序的执行。先添加进去的任务执行完毕,后面的任务再被取出放进对应的线程执行。
如果是并发队列,队列中的任务执行可以支持同时将队列中的多个任务同时放在不同线程并发执行。

// label 队列的名字
// 队列的类型 DISPATCH_QUEUE_CONCURRENT并发  DISPATCH_QUEUE_SERIAL串行
dispatch_queue_t queue = dispatch_queue_create("com.coderhong.studyProj", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t queue = dispatch_queue_create("com.coderhong.studyProj", DISPATCH_QUEUE_SERIAL);

当任务添加进队列就需要执行了。GCD提供了两个函数执行队列中的任务。dispatch_asyncdispatch_sync。这两个函数只决定有没有开线程的能力。

  • dispatch_async具备开启新的线程执行任务。
  • dispatch_sync不具备开启新的线程,只能在当前线程执行任务。

总结:
* dispatch_async + 并发队列: 开启多条线程并发执行任务
* dispatch_async + 串行队列: 开启一条线程串行发执行任务

// 创建串行队列
dispatch_queue_t queue = dispatch_queue_create("com.coderhong.studyProj", DISPATCH_QUEUE_SERIAL);
    
    // 将任务添加三个队列
    dispatch_async(queue, ^{
        // 添加任务1
        NSLog(@"----------------------1%@", [NSThread currentThread]);
        NSLog(@"----------------------1%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        // 添加任务2
        NSLog(@"----------------------2%@", [NSThread currentThread]);
        NSLog(@"----------------------2%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        // 添加任务3
        NSLog(@"----------------------3%@", [NSThread currentThread]);
        NSLog(@"----------------------3%@", [NSThread currentThread]);
    });

上面代码中我们往串行队列中添加了三个任务,使用了GCD异步函数执行,具备开线程的能力。系统此时会开启一条子线程按顺序将三个任务放进子线程中执行.

同理如果我们将队列改为并发队列。系统会开启多条线程分别将三个任务放入不同线程同时执行。开启的线程条数有系统决定。

上面通过GCD将我们的任务放在子线程中执行。队列使我们自己创建的,其实系统提供了全局的队列供我们使用。dispatch_get_main_queue和dispatch_get_global_queue

/**
  * identifier 队列的有先级 通常传递default
  * flags 一般传0
 */
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);