关于gcd一些自己的理解。

gcd这个东西对于开发ios的人应该都听说过,但是很多东西感觉理解起来感觉是有点问题。今天又看了一些关于gcd的东西,现在来说说一些我自己对理解。

我认为gcd最重要的事理解队列,还有同步任务,和异步任务。

首先是队列这个东西,很多人一开始会认为一个队列就是一个线程。这个认知是错误的,队列是什么,其实就是任务的一个集合,一个怎么样的队列决定了你里面的任务是怎么样调度的。

下面是我今天看到一个人对于队列的理解。我感觉十分的透彻。

串行队列:队列里面的任务只能一个一个的调度,比如说你三个下载图片任务,现在你只能一张一张的下载,并不能在后台同时下载三张图片。

并行队列:跟上面相反,可以同时调度三个任务,图片能在后台同时下载。

同步任务:当前指令不完成,无法进行下个指令。

怎么理解这句话,首先我们知道我们的队列都是先进先出的,下面我们来创建一个并行队列,然后同步执行下面的任务

 dispatch_queue_t queue=dispatch_queue_create("queue1", DISPATCH_QUEUE_CONCURRENT);//创建一个并行队列
    //同步运行
    dispatch_sync(queue, ^{
        NSLog(@"11111   %@",[NSThread currentThread]);
    });
    
    dispatch_sync(queue, ^{
        NSLog(@"2222    %@"    ,[NSThread currentThread]);
    });

    dispatch_sync(queue, ^{
        NSLog(@"3333   %@",[NSThread currentThread]);
    });

发现了什么问题,虽然是并行队列,意思就是可以调度几个任务的队列,但是执行的时候依然是一个一个的运行,并没有开启新的线程,都还是在主线程运行的。

为什么会造成这样的情况,就是同步任务的原因了。上面说了,同步任务就是当前指令没有执行完,下一条指令不能执行。根据先入先进的原因,我们需要执行的第一句话肯定是打印“1111”.所以这条指令没有执行完成的时候,是不能执行打印@“2222”这条指令的,当我们执行打印@“2222”这条指令的时候,打印“3333”这条指令当然也不能执行。所以即使是并行队列,但是执行的同步任务的话也并不会同时运行几个任务,因为没有必要,你必须执行完上一条指令的时候才能执行下一条。所以即使开启了线程也没用。

异步任务:就是你当前指令即使并没有执行完,你依然能执行下一个指令。

 dispatch_queue_t queue=dispatch_queue_create("queue1", DISPATCH_QUEUE_CONCURRENT);//创建一个并行队列
    //异步执行任务
    dispatch_async(queue, ^{
        NSLog(@"11111   %@",[NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"2222    %@"    ,[NSThread currentThread]);
    });

    dispatch_async(queue, ^{
        NSLog(@"3333   %@",[NSThread currentThread]);
    });

现在就能同时执行三个打印了。而且都在不同的线程执行。

我们现在来继续验证一下这个想法,我们将打印@“1111”设为同步任务,打印“2222”也变成同步任务并睡眠两秒,打印“3333”设为异步任务,来看看会怎么样

  
    dispatch_queue_t queue=dispatch_queue_create("queue1", DISPATCH_QUEUE_CONCURRENT);//创建一个并行队列
    
    dispatch_sync(queue, ^{
        NSLog(@"11111   %@",[NSThread currentThread]);
    });
    
    dispatch_sync(queue, ^{
        [NSThread sleepForTimeInterval:2.0f];
        NSLog(@"2222    %@"    ,[NSThread currentThread]);
    });

    dispatch_async(queue, ^{
        NSLog(@"3333   %@",[NSThread currentThread]);
    });

你会发现,异步任务依然是等到了同步任务都完成之后再执行的。

还有个东西就主队列,在主队列里面进行异步操作会死锁。为什么会这样啦?

因为主队列有个特性,如果主线程里面有任务是不会进行任务的调度的,但是主线程是肯定一直有任务的在运行的,因为主线成需要监视我们是否有UI操作之类的东西,所以不可能主线程有没有任务的时候。所以比如我们平时写的代码都是在主队列中异步操作的。

原文地址:https://www.cnblogs.com/xiaomingtongxue/p/4442640.html