iOS开发 GCD详解

中已有博主写的很详细,这里做个记录,方便自己日后查阅。
参考: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,看需求(有几个需要同步执行的任务,就设置为多少)
  • 有多少个需要同步执行的任务,semaphore就设置为多少
  • dispatch_semaphore_signal:发送一个信号,让信号量加1
  • dispatch_semaphore_wait:可以使总信号量减 1,信号总量小于 0 时就会一直等待(会阻塞所在线程,所以一般是加在并发队列中,让其新建线程,就不会影响当前线程),大于等于0,就可以正常执行。

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

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

你可能感兴趣的:(iOS开发 GCD详解)