美文网首页
iOS开发 GCD详解

iOS开发 GCD详解

作者: Hiker5 | 来源:发表于2020-09-17 11:34 被阅读0次

    简书中已有博主写的很详细,这里做个记录,方便自己日后查阅。
    参考:https://www.jianshu.com/p/2d57c72016c6

    一、主要概念:
    1.线程

    GCD会自动管理线程的生命周期(创建线程、调度任务、销毁线程)。只要你正确使用GCD中的队列与任务,就不需要考虑线程的生命周期问题。

    2.队列
    串行队列:一个接一个的调度任务。Dispatch Queue Serial

    // 串行队列的创建方法
    dispatch_queue_t queue = dispatch_queue_create("net.bujige.testQueue", DISPATCH_QUEUE_SERIAL);
    

    并发队列:可以同时调度多个任务。Dispatch Queue Concurrent

    // 并发队列的创建方法
    dispatch_queue_t queue = dispatch_queue_create("net.bujige.testQueue", DISPATCH_QUEUE_CONCURRENT);
    

    主队列:全局串行队列,由主线程串行调度任务,并且只有一个。Main

    可使用 dispatch_get_main_queue() 方法获得主队列。
    

    全局队列:没有名称的并发队列。Global

    // 全局并发队列的获取方法
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    

    3.任务
    同步执行任务

    // 同步执行任务创建方法
    dispatch_sync(queue, ^{
        // 这里放同步执行任务代码
    });
    

    异步执行任务

    // 异步执行任务创建方法
    dispatch_async(queue, ^{
        // 这里放异步执行任务代码
    });
    

    4.队列组 dispatch_group,关键词有
    dispatch_group_async
    dispatch_group_notify
    dispatch_group_enter
    dispatch_group_leave
    dispatch_group_wait
    调用队列组的 dispatch_group_async 先把任务放到队列中,然后将队列放入队列组中。或者使用队列组的 dispatch_group_enter、dispatch_group_leave 组合来实现 dispatch_group_async。

    例子

    /**
     * 队列组 dispatch_group_notify
     */
    - (void)groupNotify {
        NSLog(@"currentThread---%@",[NSThread currentThread]);  // 打印当前线程
        NSLog(@"group---begin");
        
        dispatch_group_t group =  dispatch_group_create();
        
        dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            // 追加任务 1
            [NSThread sleepForTimeInterval:2];              // 模拟耗时操作
            NSLog(@"1---%@",[NSThread currentThread]);      // 打印当前线程
        });
        
        dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            // 追加任务 2
            [NSThread sleepForTimeInterval:2];              // 模拟耗时操作
            NSLog(@"2---%@",[NSThread currentThread]);      // 打印当前线程
        });
        
        dispatch_group_notify(group, dispatch_get_main_queue(), ^{
            // 等前面的异步任务 1、任务 2 都执行完毕后,回到主线程执行下边任务
            [NSThread sleepForTimeInterval:2];              // 模拟耗时操作
            NSLog(@"3---%@",[NSThread currentThread]);      // 打印当前线程
    
            NSLog(@"group---end");
        });
    }
    

    5.栅栏 : 将两组异步执行的操作组给分割起来。等第一组执行完再执行第二组。dispatch_barrier_async

    /**
     * 栅栏方法 dispatch_barrier_async
     */
    - (void)barrier {
        dispatch_queue_t queue = dispatch_queue_create("net.bujige.testQueue", DISPATCH_QUEUE_CONCURRENT);
        
        dispatch_async(queue, ^{
            // 追加任务 1
            [NSThread sleepForTimeInterval:2];              // 模拟耗时操作
            NSLog(@"1---%@",[NSThread currentThread]);      // 打印当前线程
        });
        dispatch_async(queue, ^{
            // 追加任务 2
            [NSThread sleepForTimeInterval:2];              // 模拟耗时操作
            NSLog(@"2---%@",[NSThread currentThread]);      // 打印当前线程
        });
        
        dispatch_barrier_async(queue, ^{
            // 追加任务 barrier
            [NSThread sleepForTimeInterval:2];              // 模拟耗时操作
            NSLog(@"barrier---%@",[NSThread currentThread]);// 打印当前线程
        });
        
        dispatch_async(queue, ^{
            // 追加任务 3
            [NSThread sleepForTimeInterval:2];              // 模拟耗时操作
            NSLog(@"3---%@",[NSThread currentThread]);      // 打印当前线程
        });
        dispatch_async(queue, ^{
            // 追加任务 4
            [NSThread sleepForTimeInterval:2];              // 模拟耗时操作
            NSLog(@"4---%@",[NSThread currentThread]);      // 打印当前线程
        });
    }
    

    6.信号量 : dispatch_semaphore
    GCD 中的信号量是指 Dispatch Semaphore,是持有计数的信号。提供有三个方法

    • dispatch_semaphore_create:创建一个Semaphore,并初始化信号总量
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);//一般为0,在线程安全是设置为1,看需求
    
    • dispatch_semaphore_signal:发送一个信号,让信号量加1
    • dispatch_semaphore_wait:可以使总信号量减 1,信号总量小于 0 时就会一直等待(会阻塞所在线程,所以一般是加在并发队列中,让其新建线程,就不会影响当前线程),等于0,就可以正常执行。

    Dispatch Semaphore 在实际开发中主要用于:

    • 保持线程同步,将异步执行任务转换为同步执行任务
    • 保证线程安全,为线程加锁,利用dispatch_semaphore_wait等于0才执行否则阻塞所在线程的特性。(电影院两个窗口同时卖票的例子)

    相关文章

      网友评论

          本文标题:iOS开发 GCD详解

          本文链接:https://www.haomeiwen.com/subject/hxxlyktx.html