GCD

 GCD(Grand Central Dispatch)中央调度器

使用GCD只要理解两个东西 (任务 、队列);线程的创建和销毁都不需要程序员管理,非常方便好用。

一、基本使用

1、异步+并行队列  : 开启新的线程,多任务同时执行。

//创建队列
    /*
     创建并发队列 dispatch_queue_create(队列标签, 队列类型);
     队列类型:
             DISPATCH_QUEUE_CONCURRENT 并行/并发
             DISPATCH_QUEUE_SERIAL     串行
     */
    dispatch_queue_t queue1 = dispatch_queue_create("queue.label", DISPATCH_QUEUE_CONCURRENT);
    
    /*
     获取全局并发队列 dispatch_get_global_queue(优先级:一般使用Defaul, 这个暂时没用,填0就可以了);
     优先级:从上往下
            DISPATCH_QUEUE_PRIORITY_HIGH 2
            DISPATCH_QUEUE_PRIORITY_DEFAULT 0
            DISPATCH_QUEUE_PRIORITY_LOW (-2)
            DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN
     */
    dispatch_queue_t queue2 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);//一般使用全局并发队列
    /*
     dispatch_async 异步
     dispatch_sync  同步
     */
    dispatch_async(queue2, ^{
        //任务
        for (int i =0; i < 10; i++) {
            NSLog(@"---01----:%@",[NSThread currentThread]);
        }
    });
    
    dispatch_async(queue2, ^{
        //任务
        for (int i =0; i < 10; i++) {
            NSLog(@"---02----:%@",[NSThread currentThread]);
        }
    });
    
    dispatch_async(queue2, ^{
        //任务
        for (int i =0; i < 10; i++) {
            NSLog(@"---03----:%@",[NSThread currentThread]);
        }
    });

 

2、异步+串行队列 :  开启新的线程,单任务一个一个执行。

//创建队列
    /*
     创建并发队列 dispatch_queue_create(队列标签, 队列类型);
     队列类型:
     DISPATCH_QUEUE_CONCURRENT 并行/并发
     DISPATCH_QUEUE_SERIAL     串行
     */
//    dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t queue = dispatch_queue_create("queue.label", NULL);//可以填NULL,代表串行队列
    /*
     dispatch_async 异步
     dispatch_sync  同步
     */
    dispatch_async(queue, ^{
        //任务
        for (int i =0; i < 10; i++) {
            NSLog(@"---01----:%@",[NSThread currentThread]);
        }
    });
    
    dispatch_async(queue, ^{
        //任务
        for (int i =0; i < 10; i++) {
            NSLog(@"---02----:%@",[NSThread currentThread]);
        }
    });
    
    dispatch_async(queue, ^{
        //任务
        for (int i =0; i < 10; i++) {
            NSLog(@"---03----:%@",[NSThread currentThread]);
        }
    });

 

3、异步+主队列 : 不启新的线程,串行执行。

//获取主队列
    dispatch_queue_t queue = dispatch_get_main_queue();
    /*
     dispatch_async 异步
     dispatch_sync  同步
     */
    dispatch_async(queue, ^{
        //任务
        for (int i =0; i < 10; i++) {
            NSLog(@"---01----:%@",[NSThread currentThread]);
        }
    });
    
    dispatch_async(queue, ^{
        //任务
        for (int i =0; i < 10; i++) {
            NSLog(@"---02----:%@",[NSThread currentThread]);
        }
    });
    
    dispatch_async(queue, ^{
        //任务
        for (int i =0; i < 10; i++) {
            NSLog(@"---03----:%@",[NSThread currentThread]);
        }
    });

一般用于从子线程回到主线程

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);//一般使用全局并发队列
    dispatch_async(queue, ^{
        //任务
        
        //这里使用dispatch_async,异步回到主线程,而不会阻塞当前线程继续往下执行,如果需要等待主线程执行完成再往下执行就使用同步dispatch_sync
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"回到主线程");
        });
        //
        NSLog(@"这里还有执行内容。。");
    });

 

4、同步+串行队列 :不开启新的线程,在主线程中执行。

//同步只可以用串行队列,就算设置为DISPATCH_QUEUE_CONCURRENT并行队列也是无效的
    //创建队列
    //    dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t queue = dispatch_queue_create("queue.label", NULL);//可以填NULL,代表串行队列
    /*
     dispatch_async 异步
     dispatch_sync  同步
     */
    dispatch_sync(queue, ^{
        //任务
        for (int i =0; i < 10; i++) {
            NSLog(@"---01----:%@",[NSThread currentThread]);
        }
    });
    
    dispatch_sync(queue, ^{
        //任务
        for (int i =0; i < 10; i++) {
            NSLog(@"---02----:%@",[NSThread currentThread]);
        }
    });
    
    dispatch_sync(queue, ^{
        //任务
        for (int i =0; i < 10; i++) {
            NSLog(@"---03----:%@",[NSThread currentThread]);
        }
    });

 

5、同步+主队列  : 相互等待,造成线程堵塞,不执行,所以不能这么使用

NSLog(@"synMain -- start");
    
    //获取主队列
    dispatch_queue_t queue = dispatch_get_main_queue();
    /*
     dispatch_async 异步
     dispatch_sync  同步
     */
    dispatch_sync(queue, ^{
        //任务
        NSLog(@"---01----:%@",[NSThread currentThread]);
    });
    NSLog(@"synMain -- end");
    
    //打印结果 只会打印第一句 synMain -- start 然后就不执行了

 

6、barrier  特点:先执行barrier之前所以队列中的任务,再执行barrier的任务,等barrier的任务执行完成,再执行在队列中barrier之后的所有任务。

dispatch_queue_t queue = dispatch_queue_create("12312312", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_async(queue, ^{
        NSLog(@"----1-----%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"----2-----%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"----3-----%@", [NSThread currentThread]);
    });
    
    dispatch_barrier_async(queue, ^{
        NSLog(@"----barrier-----%@", [NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"----4-----%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"----5-----%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"----6-----%@", [NSThread currentThread]);
    });
    
    //执行结果:现在并发执行 1 2 3任务,再执行barrier任务 ,再并发执行 4 5 6 任务。

 

7、延迟执行

//默认放在dispatch_get_main_queue主队列中执行,可以改
    //延迟2秒
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        //延迟执行的代码
    });
    
    //其他方式
//    [self performSelector:@selector(run) withObject:nil afterDelay:2.0];
//    [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:NO];

 

8、一次性代码 : 用于单利比较多。

//一次性代码
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        //执行一次性代码,在整个程序运行期间只会执行一次。
    });

 

9、快速迭代/快速遍历 :开启多个线程同时执行任务。

//会快速开不同的线程去执行
    //dispatch_apply(执行次数, 队列, ^(size_t index);
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_apply(10, queue, ^(size_t index) {
        //快速迭代的代码,如:资料迁移。。等等。
        
    });

 

10、队列组

//创建一个队列组
    dispatch_group_t group = dispatch_group_create();
    //创建一个队列
    // 0代表默认的优先级DISPATCH_QUEUE_PRIORITY_DEFAULT
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    // 创建组
    dispatch_group_async(group, queue, ^{
        //第一个组的操作
        
        // 比如:请求1。。。 的代码
    });
    
    // 创建组
    dispatch_group_async(group, queue, ^{
        //第二个组的操作
        
        // 比如:请求2。。。 的代码
    });
    
    //
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        //当队列组都执行完成后就执行这里
        NSLog(@"两个队列中的任务都执行完成了");
    });

 

 

 

 

 

 

posted @ 2017-05-02 15:25  Gen_0  阅读(207)  评论(0编辑  收藏  举报