GCD与NSOperationQueue区别

区别


  • 1 GCD是底层的C语言构成的API,而NSOperationQueue及相关对象是Objc的对象。在GCD中,在队列中执行的是由block构成的任务,这是一个轻量级的数据结构;而Operation作为一个对象,为我们提供了更多的选择;
  • 2 在NSOperationQueue中,我们可以随时取消已经设定要准备执行的任务(当然,已经开始的任务就无法阻止了),而GCD没法停止已经加入queue的block(其实是有的,但需要许多复杂的代码);
  • 3 NSOperation能够方便地设置依赖关系,我们可以让一个Operation依赖于另一个Operation,这样的话尽管两个Operation处于同一个并行队列中,但前者会直到后者执行完毕后再执行;
  • 4 我们能将KVO应用在NSOperation中,可以监听一个Operation是否完成或取消,这样子能比GCD更加有效地掌控我们执行的后台任务;
  • 5 在NSOperation中,我们能够设置NSOperation的priority优先级,能够使同一个并行队列中的任务区分先后地执行,而在GCD中,我们只能区分不同任务队列的优先级,如果要区分block任务的优先级,也需要大量的复杂代码;
  • 6 我们能够对NSOperation进行继承,在这之上添加成员变量与成员方法,提高整个代码的复用度,这比简单地将block任务排入执行队列更有自由度,能够在其之上添加更多自定制的功能。

GCD


队列

//    //1、主队列(是串行队列)
//    dispatch_queue_t mainQueue = dispatch_get_main_queue();
//    
//    //2、全局并行队列
//    dispatch_queue_t concu = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);//两个参数,前者是优先级,后者目前用不到
//    
//    //3、创建串行队列 (自定义队列)
//    dispatch_queue_t queueSerial = dispatch_queue_create("je", DISPATCH_QUEUE_SERIAL);//两个参数,前者是名字(注意是c字符串),后者是队列类型。
//    
//    //4、创建并行队列 (自定义队列)(一般使用系统带的全局并行队列即可)
//    dispatch_queue_t queueConcu = dispatch_queue_create("jr2", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t _Queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(_Queue, ^{  
    //请求数据     
    NSData *data = [NSData dataWithContentURL:[NSURL URLWithString:@"http://domain.com/a.png"]]; 
    dispatch_async(dispatch_get_main_queue(), ^{ 
        [self refreshViews:data];
     });
});

Operation Queues


队列

 //1、主队列(是串行队列)
 NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];  
 
 //2、自定义队列
 NSOperationQueue *queue = [[NSOperationQueue alloc] init];
//普通用法
  NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];  //主队列
  NSOperationQueue *queue = [[NSOperationQueue alloc] init]; //自定义队列
  NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
        //任务执行
  }];
  [queue addOperation:operation];
//打印内容
2017-02-23 00:21:35.024 thread[5616:3d13] 执行第1次操作,线程:<NSThread: 0x7658570>{name = (null), num = 3}  
2017-02-23 00:21:35.063 thread[5616:1303] 执行第2次操作,线程:<NSThread: 0x765a2e0>{name = (null), num = 4}  
//依赖用法

NSOperationQueue *queue = [[NSOperationQueue alloc] init];  
  
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^(){  
    NSLog(@"执行第1次操作,线程:%@", [NSThread currentThread]);  
}];  
  
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^(){  
    NSLog(@"执行第2次操作,线程:%@", [NSThread currentThread]);  
}];  
// operation1依赖于operation2  
[operation1 addDependency:operation2];  
  
[queue addOperation:operation1];  
[queue addOperation:operation2]; 
//打印内容
2017-02-23 00:24:16.260 thread[5656:1b03] 执行第2次操作,线程:<NSThread: 0x7634490>{name = (null), num = 3}  
2017-02-23 00:24:16.285 thread[5656:1303] 执行第1次操作,线程:<NSThread: 0x9138b50>{name = (null), num = 4}  
// 每次只能执行一个操作  (可以试并行或者是串行,看这个参数)
queue.maxConcurrentOperationCount = 1;  
// 或者这样写  
[queue setMaxConcurrentOperationCount:1];  

// 取消单个操作  
[operation cancel];  
  
// 取消queue中所有的操作  
[queue cancelAllOperations];  

// 会阻塞当前线程,等到某个operation执行完毕  
[operation waitUntilFinished];