iOS进阶_GCD(二.GCD串行队列&并发队列)

GCD 核心概念:将任务添加到队列,指定任务执行的方法

  • 任务
    • 使用block封装
    • block 就是一个提前准备好的代码块,在需要的时候执行
  • 队列(负责调度任务)
    • 串行队列:一个接一个的调度任务
    • 并发队列:可以同时调度多个任务
  • 任务执行函数(任务都需要在线程中执行!)
    • 同步执行:当前指令不完成,不会执行下个指令
    • 异步执行:当前指令不完成,同样可以执行下一条指令

总结:
-开不开线程,取决于执行任务的函数,同步不开,异步才能开。
-开几条线程,取决于队列,串行开一条,并发可以开多条(异步)。

串行并发是根据任务来的

这里写图片描述

同步异步是根据线程来说的

iOS进阶_GCD(二.GCD串行队列&并发队列)_第1张图片

串行同步:是我们一个一个依次去队列中拿任务,由主线程依次执行任务
串行异步:是我们一个一个依次去队列中拿任务,去线程池拿一条子线程依次执行任务

并行同步:是我们依次去队列中拿多个任务,交给一条线程去顺序执行
并行异步:是我们依次去队列中拿多个任务,再去线程池拿多个子线程去执行任务

iOS进阶_GCD(二.GCD串行队列&并发队列)_第2张图片

串行队列,同步任务:不会开启线程,会顺序执行

//MARK:串行队列,同步任务
/**
 不会开启线程,会顺序执行
 */
-(void)gcdDemo1{
    //1.队列 - 串行
    /**
      1.队列名称:
      2.队列属性:DISPATCH_QUEUE_SERIAL  标示串行
     */
    dispatch_queue_t q = dispatch_queue_create("WT_queue", NULL);
    //2.同步执行任务
    dispatch_sync(q, ^{
        NSLog(@"%@",[NSThread currentThread]);
    });

//执行结果: 2018-05-04 10:45:43.324464+0800 002-GCD串行队列[1426:71131] {number = 1, name = main}在主队列中执行
}

串行队列,异步任务

//MARK:串行队列,异步任务
-(void)gcdDemo2{
    //1.队列 - 串行
    dispatch_queue_t q = dispatch_queue_create("WT_queue", NULL);
    //2.异步执行任务
    for (int i=0; i<10; i++) {
        NSLog(@"%d-----------",i);//在主线程中,占用主线程资源,执行完毕后才能打印come here
        dispatch_async(q, ^{
            NSLog(@"%@ %d",[NSThread currentThread],i);
        });
    }//只开一条线程
    NSLog(@"come here");//它在主线程中,与子线程同时执行
}

并发队列,同步步执行

//MARK:- 并发队列,同步步执行
-(void)gcdDemo4{
    /**
     问题:会开几条线程?会顺序执行吗? come here的位置?
     答案:不会,顺序执行,come here在最后打印
     */
    //1.队列 - 并发  DISPATCH_QUEUE_CONCURRENT
    dispatch_queue_t q = dispatch_queue_create("WT_queue", DISPATCH_QUEUE_CONCURRENT);

    //2.同步执行任务
    for (int i=0; i<10; i++) {
        dispatch_sync(q, ^{
            NSLog(@"%@ %d",[NSThread currentThread],i);
        });
    }
    NSLog(@"come here");
}

并发队列,异步执行

//MARK:- 并发队列,异步执行
-(void)gcdDemo3{
  /**
   问题:会开几条线程?会顺序执行吗? come here的位置?
   答案:会开多条线程,不一定会顺序执行,come here在主线程中,与子线程同时开始
   */
    //1.队列 - 并发  DISPATCH_QUEUE_CONCURRENT
    dispatch_queue_t q = dispatch_queue_create("WT_queue", DISPATCH_QUEUE_CONCURRENT);

    //2.异步执行任务
    for (int i=0; i<10; i++) {
        dispatch_async(q, ^{
            NSLog(@"%@ %d",[NSThread currentThread],i);
        });
    }
    NSLog(@"come here");
}

GCD同步任务加强

//MARK:- 并发队列,同步步执行
-(void)gcdDemo4{
    /**
     问题:会开几条线程?会顺序执行吗? come here的位置?
     答案:不会,顺序执行,come here在最后打印
     */
    //1.队列 - 并发  DISPATCH_QUEUE_CONCURRENT
    dispatch_queue_t q = dispatch_queue_create("WT_queue", DISPATCH_QUEUE_CONCURRENT);

    //2.同步执行任务
    for (int i=0; i<10; i++) {
        dispatch_sync(q, ^{
            NSLog(@"%@ %d",[NSThread currentThread],i);
        });
    }
    NSLog(@"come here");
}

在开发中,通常会将耗时操作放后台执行,有的时候,有些任务彼此有“依赖”关系
例子:登录,支付,下载(网络相关的全部放在子线程中执行)
利用同步任务,能够做到任务依赖关系,前一个任务是同步任务,它不执行完,队列就不会调度后面的任务


//MARK - 同步任务作用!
-(void)gcdDemo5{
    dispatch_queue_t loginQueue = dispatch_queue_create("WT_queue", DISPATCH_QUEUE_CONCURRENT);
    //1.用户登录
    dispatch_sync(loginQueue, ^{
        NSLog(@"用户登录  %@",[NSThread currentThread]);
    });
    for (int i=0; i<10; i++) {
        NSLog(@"%d",i);
    }
    //2.支付
    dispatch_async(loginQueue, ^{
        NSLog(@"支付  %@",[NSThread currentThread]);
    });

    //3.下载
    dispatch_async(loginQueue, ^{
        NSLog(@"下载  %@",[NSThread currentThread]);
    });

    NSLog(@"come here");
}

可以让队列调度多个任务前,指定一个同步任务。让所有的异步任务,等待同步任务执行完成,这就是依赖关系
- 同步任务,会造成一个死锁,锁住此线程

#pragma mark -<同步任务>

//MARK: - 增强版同步任务

-(void)gcdDemo6{
    //队列
    dispatch_queue_t q =dispatch_queue_create("WT_queue", DISPATCH_QUEUE_CONCURRENT);
    //任务
    void (^task)(void)=^{
        dispatch_async(q, ^{
            for (int i=0; i<10; i++) {
                NSLog(@"%d %@",i,[NSThread currentThread]);
            }
        });
        //1.用户登录
        dispatch_sync(q , ^{
            NSLog(@"用户登录  %@",[NSThread currentThread]);
        });

        //2.支付
        dispatch_async(q , ^{
            NSLog(@"支付  %@",[NSThread currentThread]);
        });

        //3.下载
        dispatch_async(q , ^{
            NSLog(@"下载  %@",[NSThread currentThread]);
        });


    };
    dispatch_async(q, task);
}

全局队列优先级&服务质量

参数
1.涉及到系统适配
iOS 8 服务质量
QOS_CLASS_USER_INTERACTIVE //用户交互(希望线程快速被执行,不要用耗时的操作)
QOS_CLASS_USER_INITIATED //用户需要的(同样不要使用耗时操作)
QOS_CLASS_DEFAULT //默认的(给系统来重置队列的)
QOS_CLASS_UTILITY //使用工具(用来做耗时操作)
QOS_CLASS_BACKGROUND //后台
QOS_CLASS_UNSPECIFIED //没有指定优先级

iOS 7 调度的优先级
- DISPATCH_QUEUE_PRIORITY_HIGH 2 //高优先级
- DISPATCH_QUEUE_PRIORITY_DEFAULT 0 //默认优先级
- DISPATCH_QUEUE_PRIORITY_LOW (-2) //低优先级
- DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN //后台优先级

 提示:不管是优先级还是服务质量,尤其不要选择BACKGROUND。如果选择线程执行会慢到令人发指!

   2.为未来使用的一个保留,现在始终给0

 在老项目中,一般还是没有淘汰iOS 7,没法使用服务质量   
//MARK: 全局队列
-(void)gcdDemo7{
    //全局队列(本质上是并发队列)

    dispatch_queue_t q = dispatch_get_global_queue(0, 0);

    for (int i=0; i<10; i++) {
        dispatch_async(q, ^{
            NSLog(@"%@ %d",[NSThread currentThread],i);
        });
    }

    NSLog(@"come here");
}

全局队列 & 并发队列 区别
1> 名称,并发队列取名字,适合于企业开发跟踪错误
2> release,在MRC 并发队列 需要使用的
dispatch_release(q);//ARC情况下不需要release!

全局队列 & 串行队列
全局队列:并发,能够调度多个线程,执行效率高
-费电
串行队列:一个一个执行,执行效率低
-省电

    判断依据:用户上网方式
     -WIFI:可以多开线程
     -流量:尽量少开线程

你可能感兴趣的:(iOS进阶,iOS开发进阶)