【iOS进阶】【多线程】1-GCD

一、GCD基本思想

1>GCD的基本思想是就将操作放在队列中去执行

  1.操作使用Blocks定义

  2.队列负责调度任务执行所在的线程以及具体的执行时间

  3.队列的特点是先进先出(FIFO)的,新添加至对列的操作都会排在队尾

  4.提示:GCD的函数都是以dispatch(分派、调度)开头的

  5.队列:dispatch_queue_t

    (1)串行队列,队列中的任务只会顺序执行。DISPATCH_QUEUE_SERIAL

    (2)并行队列,队列中的任务通常会并发执行。DISPATCH_QUEUE_CONCURRENT

  6.操作

    dispatch_async 异步操作,会并发执行,无法确定任务的执行顺序

    dispatch_sync 同步操作,会依次顺序执行,能够决定任务的执行顺序

二、GCD基本实现

1>串行队列,DISPATCH_QUEUE_SERIAL

-(void)gcdDemo1{
    //将操作放在队列中
    //在C语言函数中,定义类型,绝大多数的结尾时_t或者ref
    dispatch_queue_t q = dispatch_queue_create("cn.itcas.gcddemo", DISPATCH_QUEUE_SERIAL);
    
   //异步任务,并发执行。
  //使用串行队列,的异步任务非常非常有用
  dispatch_async(q, ^{ NSLog(@"%@",[NSThread currentThread]); }); //串行队列的同步任务,同样会在主线程上运行 //实际操作中极少用 //同步任务,顺序执行 dispatch_sync(q, ^{ //[NSThread currentThread] 可以在开发中,跟踪当前线程 //打印的 num = 1,表示主线程。 num = 2,表示第2个子线程 NSLog(@"%@",[NSThread currentThread]); }); }

2>并行队列,DISPATCH_QUEUE_CONCURRENT

#pragma mark 并行(并排跑,类似于赛跑)队列,DISPATCH_QUEUE_CONCURRENT
-(void)gcdDemo2{
    //特点:没有队形,执行顺序程序员无法控制
    //应用场景:并发执行任务,没有先后顺序
    dispatch_queue_t q = dispatch_queue_create("cn.itcas.gcd2", DISPATCH_QUEUE_CONCURRENT);

    //可以调换两个for循环来看看运行结果
  /** 
    异步操作会新建多个线程、操作无序执行(有用,容易出错!)    
    队列前如果有其他任务,会等待前面的任务完成之后再执行    
    场景:既不影响主线程,又不需要顺序执行的操作!  
  
*/  
  for(int i = 0;i<10 ; i++){ //异步任务,在并行队列中,无序 dispatch_async(q, ^{ //[NSThread currentThread] 可以在开发中,跟踪当前线程 //打印的 num = 1,表示主线程。 num = 2,表示第2个子线程 NSLog(@"%@",[NSThread currentThread]); }); } for(int i = 0;i<10 ; i++){ //同步任务,顺序执行 dispatch_sync(q, ^{ //[NSThread currentThread] 可以在开发中,跟踪当前线程 //打印的 num = 1,表示主线程。 num = 2,表示第2个子线程 NSLog(@"%@",[NSThread currentThread]); }); } }

3>全局队列,dispatch_get_global_queue

#pragma mark 全局队列(方便多线程的设计,提供来一个全局队列,供所有的APP共同使用)
-(void)gcdDemo3{
    //全局队列与并行队列的区别
    //1> 不需要创建,直接GET就能用
    //2> 两个队列的执行效果相同
    //3> 全局队列没有名称,调试时,无法确认准确队列
    //记住:开发中永远用DISPATCH_QUEUE_PRIORITY_DEFAULT(默认)
    dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    
    
    //串行队列的同步任务,同样会在主线程上运行
    //实际操作中极少用
    for(int i = 0;i<10 ; i++){
        //同步任务,顺序执行
        dispatch_sync(q, ^{
            //[NSThread currentThread] 可以在开发中,跟踪当前线程
            //打印的 num = 1,表示主线程。 num = 2,表示第2个子线程
            NSLog(@"%@",[NSThread currentThread]);
        });
    }
    for(int i = 0;i<10 ; i++){
        //异步任务,并发执行。在串行队列中,仍然会依次顺序执行
        dispatch_async(q, ^{
            //[NSThread currentThread] 可以在开发中,跟踪当前线程
            //打印的 num = 1,表示主线程。 num = 2,表示第2个子线程
            NSLog(@"%@",[NSThread currentThread]);
        });
    }
}

4>主队列,dispatch_get_main_queue() 

#pragma mark 主线程队列,保证操作在主线程上执行
-(void)gcdDemo4{
    //每一个应用程序都只有一个主线程
    //为什么需要在主线程上工作呢?
    //在iOS开发中,所有UI的更新工作,都必须在主线程上执行
    dispatch_queue_t q = dispatch_get_main_queue();
    
    //主线程是有工作多,除非将程序杀掉,否则主线程多工作不会结束
    //主线程不能做同步操作,这样会阻塞!
    //dispatch_sync(q, ^{
        //NSLog(@"%@",[NSThread currentThread]);
    //});
    
    
    //主队列中的操作都应该在主线程上顺序执行的,不存在异步的概念
    //异步任务在主线程上运行,同样是保持队形的
    for(int i = 0;i<10;i++){
        dispatch_async(q, ^{
            NSLog(@"%@",[NSThread currentThread]);
        });
    }
}

5>dispatch_sync的应用场景

//阻塞并行队列的执行,要求某一操作执行后再进行后续操作,如用户登录
//确保块代码之外的局部变量确实被修改
dispatch_queue_t q = dispatch_queue_create("cn.itcast.gcddemo", DISPATCH_QUEUE_CONCURRENT);
__block BOOL logon = NO;
dispatch_sync(q, ^{
    NSLog(@"模拟耗时操作 %@", [NSThread currentThread]);
    [NSThread sleepForTimeInterval:2.0f];
    NSLog(@"模拟耗时完成 %@", [NSThread currentThread]); 
    logon = YES;
});

dispatch_async(q, ^{
       NSLog(@"登录完成的处理 %@", [NSThread currentThread]);
});

三、GCD小结

1>GCD

  1.通过GCD,开发者不用再直接跟线程打交道,只需要向队列中添加代码块即可

  2.GCD在后端管理着一个线程池,GCD不仅决定着代码块将在哪个线程被执行,它还根据可用的系统资源对这些线程进行管理。

   从而让开发者从线程管理的工作中解放出来,通过集中的管理线程,缓解大量线程被创建的问题

  3.使用GCD,开发者可以将工作考虑为一个队列,而不是一堆线程,这种并行的抽象模型更容易掌握和使用

2>GCD的队列

  1.GCD公开有5个不同的队列:运行在主线程中的主队列,3 个不同优先级的后台队列,以及一个优先级更低的后台队列(用于 I/O)

  2.自定义队列:串行和并行队列。自定义队列非常强大,建议在开发中使用。在自定义队列中被调度的所有Block最终都将被放入到系统

   的全局队列中和线程池中

提示:不建议使用不同优先级的队列,因为如果设计不当,可能会出现优先级反转,即低优先级的操作阻塞高优先级的操作

3>GCD队列示意图

      

posted @ 2015-04-21 19:51  锟斤拷Dy  阅读(136)  评论(0)    收藏  举报