项目中使用NSOperation的优点是NSOperation是对线程的高度抽象,在项目中使用它,会使项目的程序结构更好子类化NSOperation的设计思路,是具有面向对象的优点(复用、封装),使得实现是多线程支持,而接口简单,建议在复杂项目中使用。使用GCD的优点是GCD本身非常简单、易用,对于不复杂的多线程操作,会节省代码量,而Block参数的使用,会是代码更为易读,建议在简单项目中使用。
NSOperation 与 GCD 的对比
- GCD
将任务(block)添加到队列(串行/并发/主队列),并且指定任务执行的函数(同步/异步)
GCD是底层的C语言构成的API
iOS 4.0 推出的,针对多核处理器的并发技术
在队列中执行的是由 block 构成的任务,这是一个轻量级的数据结构
要停止已经加入 queue 的 block 需要写复杂的代码
需要通过 Barrier 或者同步任务设置任务之间的依赖关系
只能设置队列的优先级
高级功能:
一次性 once
延迟操作 after
调度组
- NSOperation
核心概念:把操作(异步)添加到队列(全局的并发队列)
OC 框架,更加面向对象,是对 GCD 的封装
iOS 2.0 推出的,苹果推出 GCD 之后,对 NSOperation 的底层全部重写
Operation作为一个对象,为我们提供了更多的选择
可以随时取消已经设定要准备执行的任务,已经执行的除外
可以跨队列设置操作的依赖关系
可以设置队列中每一个操作的优先级
高级功能:
最大操作并发数(GCD不好做)
继续/暂停/全部取消
跨队列设置操作的依赖关系
全局队列 /// 全局操作队列,统一管理所有的异步操作 @property (nonatomic, strong) NSOperationQueue *queue; - (NSOperationQueue *)queue { if (_queue == nil) { _queue = [[NSOperationQueue alloc] init]; } return _queue;} 最大并发操作数 /// MARK: - 最大并发操作数 - (void)opDemo1 { // 设置同时并发操作数 self.queue.maxConcurrentOperationCount = 2; NSLog(@"start"); for (int i = 0; i < 10; ++i) { NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{ [NSThread sleepForTimeInterval:1.0]; NSLog(@"%@ %d", [NSThread currentThread], i); }]; [self.queue addOperation:op]; } } 暂停 & 继续 /// MARK: - 暂停 & 继续 - (IBAction)pauseAndResume { if (self.queue.operationCount == 0) { NSLog(@"没有操作"); return; } // 暂停或者继续 self.queue.suspended = !self.queue.isSuspended; if (self.queue.isSuspended) { NSLog(@"暂停 %tu", self.queue.operationCount); } else { NSLog(@"继续 %tu", self.queue.operationCount); } } 队列挂起,当前"没有完成的操作",是包含在队列的操作数中的 队列挂起,不会影响已经执行操作的执行状态 对列一旦被挂起,再添加的操作不会被调度 取消全部操作 /// MARK: - 取消所有操作 - (IBAction)cancelAll { if (self.queue.operationCount == 0) { NSLog(@"没有操作"); return; } // 取消对列中的所有操作,同样不会影响到正在执行中的操作! [self.queue cancelAllOperations]; NSLog(@"取消全部操作 %tu", self.queue.operationCount); } 1 取消队列中所有的操作 2 不会取消正在执行中的操作 3 不会影响队列的挂起状态 依赖关系 /// MARK: - 依赖关系 - (void)dependency { NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"登录 %@", [NSThread currentThread]); }]; NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"付费 %@", [NSThread currentThread]); }]; NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"下载 %@", [NSThread currentThread]); }]; NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"通知用户 %@", [NSThread currentThread]); }]; [op2 addDependency:op1]; [op3 addDependency:op2]; [op4 addDependency:op3]; // 注意不要循环依赖 // [op1 addDependency:op4]; [self.queue addOperations:@[op1, op2, op3] waitUntilFinished:NO]; [[NSOperationQueue mainQueue] addOperation:op4]; NSLog(@"come here"); }