伟大的GCD和NSOperationQueue

   一、 GCD

GCD中最重要的两个东西 任务 和 队列

任务就是一段代码(用来缓存,下载,计算等操作) 

队列从大的方面分为两个队列:主队列(串行队列)和 自己创建的队列(串行,和并行)

主队列中:

在主队列中不能开启新的线程出来(所以同步和异步的效果是一样的,但是按钮会回弹上来,变成可以点击的样子,但是实际点击了也是无效的)

在主队列中,不能执行同步的方法,主线程的方法执行完,才会执行主线程方法里的主线程方法,这样就会两个任务互相等待! 而异步就可以把主任务暂时挂起,先执行完主线程的任务,然后在执行主线程的任务中的主线程任务

在自己创建的队列中

串行:遵循FIFO(先进先出原则)

并行:也遵循FIFO原则,但是有所不同

其中任务的执行又分成两种方式

同步执行:(sync) 同步执行只会在当前队列的主线程中执行,并不会另开一个线程

异步执行:(async)异步执行则会另外开一个线程,并不会再主线程中执行

两个特性决定了同步执行容易堵塞线程,而且当同步执行时,其他的操作都不能进行

或者说同步执行他会阻塞当前线程要等待当前任务执行完才会继续往下执行,但是异步执行的话就会执行下去,不会阻塞线程

应该就是上述图的样子233

两种队列和两种执行方式交叉共有4个形式

串行同步:在串行队列的线程中执行任务,不执行完一个任务,不能继续下一个任务(而且按钮在任务完成以前是不会回弹成可点击的样子)

 

串行异步:在串行队列中开启一个子线程进行任务,在第一个任务执行完成之前,不能执行下一个任务,但是不会干扰启动主线程的任务

 

并行同步:同步是不具备开,子线程的能力的,但是并行只有开起子线程的时候才能起作用,所以并行同步,没有意义就像串行同步

 

并行异步: 可以开启多个子线程进行任务,并且不会干扰启动主线程任务

这里的不会干扰启动主线程任务是由队列的主线程是否执行任务来决定的。

//一个特殊的情况

如果在并行队列中一个异步执行的block中执行一个同步的方法,那么这个同步不会阻塞主线程,但是他会等同步的block执行完以后,才会往下执行下去,因为是并行队列,所以可以开启一个子线程

因为比较难以理解,所以苹果就自己封装了一个类NSOperationQueue

 //操作属于模型层,不分主线程和子线程。
    NSInvocationOperation *IO = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downLoadImage) object:nil];
    //操作需要添加到操作队列里面,操作队列就会自动添加到子线程中(可以开启多条子线程来执行任务)
    //操作队列只需要添加 操作进来,开启多少条子线程不需要管,什么时候回收也不需要管,但是需要我们人为的创建操作,并且需要创建队列。
     NSOperationQueue *queue = [[NSOperationQueue alloc] init];
   
    [queue addOperation:IO];
    
    NSBlockOperation *BO = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"%@, %d",[NSThread currentThread], [NSThread isMainThread]);
    }];
    [queue addOperation:BO];

相对于GCD,这个就比较好理解和管理了。

原文地址:https://www.cnblogs.com/naizui/p/5269912.html