• 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(@"两个队列中的任务都执行完成了");
        });
  • 相关阅读:
    编写安全有效的 C# 代码
    模式匹配
    C#新特性
    转 C# .NET4.0 混合模式程序集异常
    win7 64位系统 注册 ocx控件
    TIFF图像文件格式详解
    GDALOGR读取数据示例 C#版本
    使用gdal C#封装库读取DEM数据
    编译C#环境下GDAL(支持HDF4、NetCDF)
    UML类图符号 各种关系说明以及举例
  • 原文地址:https://www.cnblogs.com/qq9070/p/6796289.html
Copyright © 2020-2023  润新知