GCD

GCD

Grand Central Dispatch是异步执行任务的技术之一。
GCD是苹果公司为多核的并行运算提出的解决方案
GCD会自动利用更多的CPU内核(比如双核、四核)
GCD会自动管理线程的生命周期(创建线程、调度任务、销毁线程)
程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码

一个例子
  dispatch_async(queue, ^{
       
        /*
         *长时间处理
         */
        
        /*
         *长时间处理结束,主线程使用该处理结果
         *
         */
        dispatch_async(dispatch_get_main_queue(), ^{
            /*
             *只在主线程中可以执行的结果
             *例如  更新UI
             */
        });
    });
    其中queue是队列
    block是任务

在多线程编程中容易发生各种问题。比如多线程更新相同的数据、死锁、使用线程太多大量消耗内存等。采用GCD技术大大简化了复杂的多线程编程

Dispatch Queue

开发者要做的只是定义想执行的任务并追加到适当的Dispatch Queue中。

dispatch_async(queue, ^{ 
        /*
         *想执行的任务
         */
    });

任务的取出遵循队列的FIFO原则:先进先出,后进后出。
另外在执行处理的时候存在两种Dispatch Queue,一种是等待现在执行中处理的Serial Dispatch Queue,另一种是不等待现在执行中处理的Concurrent Dispatch Queue。


GCD_第1张图片
并行视图
GCD_第2张图片
串行视图

创建 dispatch_queue_create()

dispatch_queue_create(const char *label, dispatch_queue_attr_t attr)

dispatch_queue_t queue = dispatch_queue_create("gcd", NULL);
dispatch_queue_create("gcd", DISPATCH_QUEUE_CONCURRENT)

注意:系统对于一个Serial Dispatch Queue就只生成并使用一个线程。如果生成200个Serial Dispatch Queue,那么就生成200个线程
但是每个queue里面的多个任务还是一个一个的执行。
多个线程更新相同数据是可以使用Serial Dispatch Queue

Main Dispatch Queue/Global Dispatch Queue

dispatch_get_main_queue();
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
           
            //可并行执行的处理
            dispatch_async(dispatch_get_main_queue(), ^{
               //主线程中处理
            });
        });

dispatch_set_target_queue

dispatch_queue_create()生成的Queue,使用与默认优先级Global Dispatch Queue相同执行优先级的线程。而变更生成的Queue的执行优先级需要使用dispatch_set_target_queue这个函数

dispatch_set_target_queue(<#dispatch_object_t object#>, <#dispatch_queue_t queue#>)
指定第一个Queue与第二个Queue相同的优先级。

dispatch_after

在1s后将指定的block追加到Main Queue中执行

dispatch_after函数是指定时间追加而不是指定时间处理


 dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 1*NSEC_PER_SEC);
    dispatch_after(time, dispatch_get_main_queue(), ^{
        NSLog(@"wait");
    });

Dispatch Group

在追加到Dispatch Queue中的多个处理全部结束之后想执行结束处理,这种会经常出现。在使用Current Dispatch的情况下使用Dispatch Group就可以实现

 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
 dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, queue, ^{
        NSLog(@"hehe1");
    });
    
    dispatch_group_async(group, queue, ^{
        NSLog(@"hehe2");
    });
    dispatch_group_async(group, queue, ^{
        NSLog(@"hehe3");
    });
    dispatch_group_async(group, queue, ^{
        NSLog(@"hehe4");
    });
    dispatch_group_notify(group, queue, ^{
        NSLog(@"over");
    });
2016-06-09 17:21:02.564 GCD[2874:227806] hehe3
2016-06-09 17:21:02.564 GCD[2874:227802] hehe2
2016-06-09 17:21:02.564 GCD[2874:227804] hehe1
2016-06-09 17:21:02.564 GCD[2874:227813] hehe4
2016-06-09 17:21:02.565 GCD[2874:227813] over

多个线程并行执行,所以追加处理执行的顺序不定,但是 over一定在最后才执行这里有一个好例子给大家

Dispatch Semaphore

Dispatch Semaphore是持有计数的信号,该基数是多线程编程中的计数信号类型。当计数为0时等待,计数为1或者大于1,减去1而不等待。

//创建一个计数为0的信号
 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    NSMutableArray *muArray = [[NSMutableArray alloc] init];
        dispatch_async(queue, ^{
            for (int i=0; i<100; i++) {
                [muArray addObject:@(i)];
            }
            dispatch_semaphore_signal(semaphore);  //计数+1
        });
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    NSLog(@"===>%d",[muArray count]);
    2016-06-09 17:49:14.300 GCD[2984:246535] ===>100
    如果没有则Dispatch Semaphore
    2016-06-09 17:57:55.160 GCD[3023:249929] ===>0

上例中创建一个计数为0的信号 等待

dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);等待Dispatch Semaphore计数达到大于或者等于1。当计数达到或者大于1是,对该计数进行减法并从dispatch_semaphore_wait函数返回
通过dispatch_semaphore_signal(semaphore); 将Dispatch Semaphore计数+1

一个大神的GCD封装

你可能感兴趣的:(GCD)