NSOperation(队列是任务的载体)
//创建操作(单独创建操作要调用start)
NSOperation *invocation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadImage) object:nil];
//开始操作(不添加到队列,是在主线程运行)
[invocation start];
//将操作放到队列中,不需要start(自动异步执行)
NSOperationQueue *queque = [[NSOperationQueue alloc] init];
[queque addOperation:invocation];
//把多个操作放到队列
[queque addOperation:invocation];
[queque addOperation:invocation];
[queque addOperation:invocation];
注意:队列中的操作只能添加一次,文章中重复添加是为了简化代码,不要模仿
//GCD中并发队列使用最多,所以NSOpration把GCD里面的并发队列封装起来
//NSOprationQueue队列本质就是GCD里面的并发队列
//操作就是GCD异步执行的任务
//block放到队列
NSOperation *block = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"%@",[NSThread currentThread]);
}];
//把操作放到队列
[queue addOperation:block];
[queue addOperation:block];
[queue addOperation:block];
//快速调用方法
[queue addOperationWithBlock:^{
NSLog(@"111");
}];
//在block里面还可以添加block(异步执行,不是在block之后才开始)
NSBlockOperation *block = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"%@",[NSThread currentThread]);
}];
[block addExecutionBlock:^{
NSLog(@"%@", [NSThread currentThread]);
}];
//快速创建队列更新UI(重要)
- (void)connectWithThread{
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperationWithBlock:^{
NSLog(@"耗时操作");
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
NSLog(@"更新UI");
}];
}];
}
只要是NSOpration的子类都能添加到操作队列
一旦添加就会异步执行
没有添加,要调用start方法,在当前线程通讯
如果要做线程间通信,可以使用[NSOpration mainQueue]拿到主队列,往主队列添加操作(更新UI)
//设置最大并发数(不是线程的数量,而是同时执行任务的数量,执行完任务的线程不一定马上执行下一任务,要放到线程池)
self.queue.maxConcurrentOperationCount = 2;
//让队列挂起
self.queue.suspended = YES;
//确定操作是否为0
self.queue.operationCount == 0
//取消队列所有操作(不会改变队列的挂起状态),一般,取消后会(删除所有任务)设置挂起状态,以便于队列的继续
[self.queue cancelAllOperations];
//添加依赖关系,等待上面操作结束
[op2 addDependency:op1];
NSOperation和GCD的区别
GCD:
将任务(block)添加到队列(串行/并行(全局)),指定任务的方法(同步/异步)
拿到dispatch_get_main_queue()线程间通讯
NSOpration无法做到,一次性执行,,延迟执行,调度组
NSOpration:
将操作(异步执行)添加到队列(并发/全局)
[NSOprationQueue mainQueue]任务添加到主队列,就会在主线程执行
提供了一些GCD不好实现的,最大并发数
暂停,继续——挂起
取消所有任务
依赖关系
GCD是基于c的底层api,NSOperation属于object-c类。iOS首先引入的是NSOperation,IOS4之后引入了GCD和NSOperationQueue并且其内部是用gcd实现的。
相对于GCD:1,NSOperation拥有更多的函数可用,具体查看api。
2,在NSOperationQueue中,可以建立各个NSOperation之间的依赖关系。
3,有kvo,可以监测operation是否正在执行(isExecuted)、是否结束(isFinished),是否取消(isCanceld)。
4,NSOperationQueue可以方便的管理并发、NSOperation之间的优先级。
GCD主要与block结合使用。代码简洁高效。
GCD也可以实现复杂的多线程应用,主要是建立个个线程时间的依赖关系这类的情况,但是需要自己实现相比NSOperation要复杂。
具体使用哪个,依需求而定。 从个人使用的感觉来看,比较合适的用法是:除了依赖关系尽量使用GCD,因为苹果专门为GCD做了性能上面的优化。
GCD仅仅支持FIFO队列,而NSOperationQueue中的队列可以被重新设置优先级,从而实现不同操作的执行顺序调整。
GCD不支持异步操作之间的依赖关系设置。如果某个操作的依赖另一个操作的数据(生产者-消费者模型是其中之一),使用NSOperationQueue能够按照正确的顺序执行操作。GCD则没有内建的依赖关系支持。
NSOperationQueue支持KVO,意味着我们可以观察任务的执行状态。
了解以上不同,我们可以从以下角度来定义原则
1. 性能
GCD更接近底层,而NSOperationQueue则更高级抽象,所以GCD在追求性能的底层操作来说,是速度最快的。这取决于使用Instruments进行代码性能分析,如有必要的话
2. 从异步操作之间的事务性,顺序行,依赖关系。GCD需要自己写更多的代码来实现,而NSOperationQueue已经内建了这些支持
3. 如果异步操作的过程需要更多的被交互和UI呈现出来,NSOperationQueue会是一个更好的选择。底层代码中,任务之间不太互相依赖,而需要更高的并发能力,GCD则更有优势