iOS多线程 GCD总结

在开发中涉及多线程一般会用GCD 因为强大且方便,以下是我对GCD的一些总结


任务
分为同步执行(sync)和异步执行(async)二种
同步执行

同步添加任务到指定的队列中,在添加的任务执行结束之前,会一直等待,直到队列里面的任务完成之后再继续执行。
只能在当前线程中执行任务,不具备开启新线程的能力

异步执行

异步添加任务到指定的队列中,它不会做任何等待,可以继续执行任务。
可以在新的线程中执行任务,具备开启新线程的能力
注意:异步执行(async)虽然具有开启新线程的能力,但是并不一定开启新线程。


队列(Dispatch Queue)
指用来存放任务的队列,是一种特殊的线性表,采用 FIFO(先进先出)的原则,分为二种队列:串行队列并发队列
串行队列(Serial Dispatch Queue)

每次只有一个任务被执行。让任务一个接着一个地执行。(只开启一个线程,一个任务执行完毕后,再执行下一个任务)

并发队列(Concurrent Dispatch Queue)

可以让多个任务并发(同时)执行。(可以开启多个线程,并且同时执行任务)

二者区别可以画个图解释


iOS多线程 GCD总结_第1张图片
串行队列.png

iOS多线程 GCD总结_第2张图片
并发队列png

GCD 的使用步骤
1.创建一个队列(串行队列或并发队列)
2.将任务追加到任务的等待队列中,然后系统就会根据任务类型执行任务(同步执行或异步执行)


队列的创建方法
第一个参数表示队列的唯一标识符,根据个人想法填,约束不大。第二个参数用来识别是串行队列还是并发队

// 串行队列的创建方法
dispatch_queue_t queue = dispatch_queue_create("text", DISPATCH_QUEUE_SERIAL);
// 并发队列的创建方法
dispatch_queue_t queue = dispatch_queue_create("text", DISPATCH_QUEUE_CONCURRENT);
  • 还有一些特殊的队列
    主队列(Main Dispatch Queue):所有放在主队列中的任务,都会放到主线程中执行
// 主队列的获取
dispatch_queue_t queue = dispatch_get_main_queue();

全局并发队列(Global Dispatch Queue):就是一个系统提供的并发队列吧
第一个参数表示队列优先级,一般用DISPATCH_QUEUE_PRIORITY_DEFAULT,第二个参数不知道干嘛的,一般为0

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

任务的创建

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

以上是GCD使用需要了解的............


然后会产生疑惑,任务和队列方式可以有6种

1.同步执行 + 并发队列
2.异步执行 + 并发队列
3.同步执行 + 串行队列
4.异步执行 + 串行队列
5.同步执行 + 主队列
6.异步执行 + 主队列

这里不做复杂演示,你可以直接查看表格结果


iOS多线程 GCD总结_第3张图片

End 显然不是的


GCD线程间的切换

//    获取全局并发队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//    随便创建一个任务  模拟网络等耗时操作
    dispatch_async(queue, ^{
        for (int i  = 0; i < 5; i++) {
             [NSThread sleepForTimeInterval:2];
             NSLog(@"1---%@",[NSThread currentThread]);
        }
        
//        回到主线程
        dispatch_async(dispatch_get_main_queue(), ^{
//        回到主线程进行UI操作
        });
        
    });

GCD 栅栏方法:dispatch_barrier_async
有这样一个需求,先执行某个异步操作,这个异步操作执行完成后再执行接下来的异步操作,这种情况就要用到栅栏了·。

iOS多线程 GCD总结_第4张图片
barrier 图解.png

    
    dispatch_queue_t queue = dispatch_queue_create("text", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_async(queue, ^{
        // 追加任务1
        for (int i = 0; i < 2; ++i) {
            [NSThread sleepForTimeInterval:2];              // 模拟耗时操作
            NSLog(@"1---%@",[NSThread currentThread]);      // 打印当前线程
        }
    });
    dispatch_async(queue, ^{
        // 追加任务2
        for (int i = 0; i < 2; ++i) {
            [NSThread sleepForTimeInterval:2];              // 模拟耗时操作
            NSLog(@"2---%@",[NSThread currentThread]);      // 打印当前线程
        }
    });
    
    dispatch_barrier_async(queue, ^{
        // 追加任务 barrier
        for (int i = 0; i < 2; ++i) {
            [NSThread sleepForTimeInterval:2];              // 模拟耗时操作
            NSLog(@"barrier---%@",[NSThread currentThread]);// 打印当前线程
        }
    });
    
    dispatch_async(queue, ^{
        // 追加任务3
        for (int i = 0; i < 2; ++i) {
            [NSThread sleepForTimeInterval:2];              // 模拟耗时操作
            NSLog(@"3---%@",[NSThread currentThread]);      // 打印当前线程
        }
    });
    dispatch_async(queue, ^{
        // 追加任务4
        for (int i = 0; i < 2; ++i) {
            [NSThread sleepForTimeInterval:2];              // 模拟耗时操作
            NSLog(@"4---%@",[NSThread currentThread]);      // 打印当前线程
        }
    });
    

打印发现 3和4 都是在barrier执行完后执行的


GCD 延时执行方法:dispatch_after:延迟几秒后执行

 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        // 3.0秒后异步追加任务代码到主队列,并开始执行
        NSLog(@"after---%@",[NSThread currentThread]);  // 打印当前线程
    });

GCD 一次性代码(只执行一次):dispatch_once
常在单例中看到

//一次性代码(只执行一次)dispatch_once
+ (PCCurrentUserMgr *)shareInstance {
    static PCCurrentUserMgr *s_ins = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
 // 只执行1次的代码(这里面默认是线程安全的)
        s_ins = [PCCurrentUserMgr new];
    });
    return s_ins;
}

未完待续

你可能感兴趣的:(iOS多线程 GCD总结)