iOS线程②GCD

GCD的基本概念

  • 1.GCD和NSThread的区别,GCD不需要程序员管理线程的生命周期,NSThread需要程序员手动管理生命周期

  • 2.学习GCD之前需要先弄清一些概念

    • 任务:执行什么样的操作
    • 队列:用来存放任务
      • 因为GCD不用程序员管理线程的声明周期,因此可以不管线程的创建和销毁
  • 3.GCD的使用步骤

    • 1.定制任务:确认想做的事情
    • 2.将任务添加到队列中:GCD会自动将队列中的任务取出,放到对应的线程中执行
      • 任务的取出遵循队列的FIFO原则:先进先出,后进后出。(这里需要和栈区分开来,栈是先进后出,因为,栈只有一个出口)
  • 4.GCD中的任务

    • GCD中有两个用来执行任务的常用函数
      • 同步方式执行任务
        • dispatch_sync(dispatch_queue_t _Nonnull queue, <^(void)block>)
      • 异步方式执行任务
        • dispatch_async(dispatch_queue_t _Nonnull queue, <^(void)block>)
    • 同步和异步的区别
      • 同步:只能在当前线程中执行任务,不具备开线程的能力
      • 异步:可以在新的线程中执行任务,具备开启新线程的能力
  • 5.GCD队列的类型

    • 并发队列(Concurrent Dispatch Queue)
      • 可以让多个任务并发(同时)执行,自动开启多个线程同时执行任务
      • 并发功能再有在异步 (dispatch_async)函数下才有效
    • 串行队列(Serial Dispatch Queue)
      • 让任务一个接着一个地执行,一个任务执行完毕后,再执行下一个任务
  • 6.GCD任务和队列代码详述


@interface ViewController ()

@end

@implementation ViewController

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self globlQueueAsyncCoucurrent];
}
//异步函数+串行队列:会开线程,开一条线程,队列中的任务是串行执行
-(void)asyncConcurrent
{
    //1.创建队列
    
  /**
   const char *_Nullable label:C语言字符串,线程的标签
   dispatch_queue_attr_t _Nullable attr:队列的类型
        DISPATCH_QUEUE_CONCURRENT:并发
        DISPATCH_QUEUE_SERIAL:串行
   */
  dispatch_queue_t asyncQueue =   dispatch_queue_create("lxc", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(asyncQueue, ^{
        NSLog(@"queue1---%@",[NSThread currentThread]);
    });
    //2.封装任务->添加任务到队列中
    /**
     dispatch_queue_t queue:队列是哪个
     dispatch_block_t block:block参数
     */
    dispatch_async(asyncQueue, ^{
        NSLog(@"queue2---%@",[NSThread currentThread]);
    });
    dispatch_async(asyncQueue, ^{
        NSLog(@"queue3---%@",[NSThread currentThread]);
    });
    dispatch_async(asyncQueue, ^{
        NSLog(@"queue4---%@",[NSThread currentThread]);
    });
    NSLog(@"----end----");
    //线程没有顺序
}
//异步函数+串行队列:会一条开线程,队列中的任务是串行执行
-(void)asyncSerial
{
    dispatch_queue_t asyncQueue =  dispatch_queue_create("cyf", DISPATCH_QUEUE_SERIAL);
    
    dispatch_async(asyncQueue, ^{
        NSLog(@"queue1---%@",[NSThread currentThread]);
    });
    dispatch_async(asyncQueue, ^{
        NSLog(@"queue2---%@",[NSThread currentThread]);
    });
    dispatch_async(asyncQueue, ^{
        NSLog(@"queue3---%@",[NSThread currentThread]);
    });
    dispatch_async(asyncQueue, ^{
        NSLog(@"queue4---%@",[NSThread currentThread]);
    });
    NSLog(@"----end----");
    
}
//同步函数+并行队列:不会开启线程,所有任务都在主线程中执行,队列中的任务是并行执行
-(void)syncConcurent
{
    dispatch_queue_t syncQueue =  dispatch_queue_create("23", DISPATCH_QUEUE_CONCURRENT);
    dispatch_sync(syncQueue, ^{
        NSLog(@"syncQueue1----%@",[NSThread currentThread]);
    });
    dispatch_sync(syncQueue, ^{
        NSLog(@"syncQueue2----%@",[NSThread currentThread]);
    });
    dispatch_sync(syncQueue, ^{
        NSLog(@"syncQueue3----%@",[NSThread currentThread]);
    });
    dispatch_sync(syncQueue, ^{
        NSLog(@"syncQueue4----%@",[NSThread currentThread]);
    });
}
//同步函数+串行队列:不会开启线程,所有的任务都在主线程中执行,队列中的任务是串行执行
-(void)syncSerial
{
    dispatch_queue_t syncQueue = dispatch_queue_create("22", DISPATCH_QUEUE_SERIAL);
    
    dispatch_sync(syncQueue, ^{
        NSLog(@"syncQueue1----%@",[NSThread currentThread]);
    });
    dispatch_sync(syncQueue, ^{
        NSLog(@"syncQueue2----%@",[NSThread currentThread]);
    });
    dispatch_sync(syncQueue, ^{
        NSLog(@"syncQueue3----%@",[NSThread currentThread]);
    });
    dispatch_sync(syncQueue, ^{
        NSLog(@"syncQueue4----%@",[NSThread currentThread]);
    });
    NSLog(@"---end---");
}
//全局并发队列+并发:不会创建线程,会从GCD本身就有全局并发队列,只是拿出,并且创建多少线程不受控制
-(void)globlQueueAsyncCoucurrent
{
    
    /*
     //获得全局并发队列:
    第一个参数:队列的优先级
        DISPATCH_QUEUE_PRIORITY_DEFAULT 默认 0
        DISPATCH_QUEUE_PRIORITY_HIGH 最高    2
        DISPATCH_QUEUE_PRIORITY_BACKGROUND 最低优先级 -1
        DISPATCH_QUEUE_PRIORITY_LOW 低优先级  1
     第二个参数:传0即可
     */
    //获得全局并发队列,这个队列本身是存在的,在GCD中本身就有全局并发队列,只是拿过来用一下,需要注意的是全局并发队列,是不受控制的,并不是有多少任务就先多少线程
   dispatch_queue_t globlQueue =  dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(globlQueue, ^{
        NSLog(@"asyncQueue1----%@",[NSThread currentThread]);
    });
    dispatch_async(globlQueue, ^{
        NSLog(@"asyncQueue2----%@",[NSThread currentThread]);
    });
    dispatch_async(globlQueue, ^{
        NSLog(@"asyncQueue3----%@",[NSThread currentThread]);
    });
    dispatch_async(globlQueue, ^{
        NSLog(@"asyncQueue4----%@",[NSThread currentThread]);
    });
    //全局并发队列没有顺序
}
@end

  • 7.GCD的常用函数

    • 定时任务和单例函数
dispatch_queue_t queue = dispatch_get_global_queue(0,0);
    /**
     *  @param DISPATCH_TIME_NOW 从现在开始计算时间
     *  @param int64_t 延迟的时间 2.0 GCD时间单位:纳秒
     *  @dispatch_get_main_queue 队列 
     CGD的定时任务可以控制几秒后再那个线程中执行
     */
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), queue, ^{
        NSLog(@"-----GCD------%@",[NSThread currentThread]);
    });
    //一次性代码
    //不能放在懒加载中的,应用场景:单例模式
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSLog(@"---once----");
    });
- ##### 栅栏函数
    dispatch_queue_t queue = dispatch_queue_create("download", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        NSLog(@"download1-----%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"download2-----%@",[NSThread currentThread]);
    });
    /**
     *  GCD栅栏函数
        该函数可以控制多线程异步的执行顺序(哪个先执行哪个后执行)
        注意:在使用栅栏函数的时候不可以使用全局并发队列
     */
    dispatch_barrier_async(queue, ^{
        NSLog(@"+++++++++++++++");
    });
    dispatch_async(queue, ^{
        NSLog(@"download4-----%@",[NSThread currentThread]);
    });
  • 遍历函数
         @param 10 迭代的次数
         @param 队列(并发队列)
         @param index 索引

         @return
         
        dispatch_apply(10, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t index) {
            NSLog(@"%zd-----%@",index,[NSThread currentThread]);
            
  • GCD队列组函数
    • 队列组
      • 如果有这么一种需求,首先分别异步执行2个耗时操作,其次等2个异步操作都执行完毕后,再回到主线程执行操作。如果遇到这种业务可以考虑用队列组实现
//1.创建队列
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    //2.创建队列组
    dispatch_group_t group =  dispatch_group_create();
    //3.队列组函数
    /**
     1.封装任务
     2.把任务添加到队列中
     3.会监听任务的执行情况,通知group
     */
    dispatch_group_async(group, queue, ^{
        NSLog(@"1----%@",[NSThread currentThread]);
    });
    dispatch_group_async(group, queue, ^{
        NSLog(@"2----%@",[NSThread currentThread]);
    });
    dispatch_group_async(group, queue, ^{
        NSLog(@"3----%@",[NSThread currentThread]);
    });
    
    //监听通知,当队列组中所有的任务都执行完毕的时候,进入到下面的方法
    /**
     *  监听通知的时候函数不会阻塞,内部本身是异步的
     */
  dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        
       NSLog(@"end---%@",[NSThread currentThread]);
    });
    /**
     监听通知的另一个函数,这个函数会一直等待,死等。直到队列组中所有的任务都执行完毕之后才能执行,内部本身是同步的
     */
    dispatch_group_wait(group, DISPATCH_TIME_NOW);
    NSLog(@"----end----");

你可能感兴趣的:(iOS线程②GCD)