NSOperation、NSOperationQueue 是苹果提供给我们的一套多线程解决方案。 NSOperation、NSOperationQueue 是基于 GCD 更高一层的封装,完全面向对象。但是比 GCD 更简单易用、代码可读性也更高。
操作(Operation):操作就是你在线程中执行的那段代码。使用 NSOperation 子类 NSInvocationOperation、NSBlockOperation,或者自定义子类来封装操作
操作队列(Operation Queues):这里的队列指操作队列,即用来存放操作的队列。
不同于 GCD 中的调度队列 FIFO(先进先出)的原则。NSOperationQueue 对于添加到队列中的操作,首先进入准备就绪的状态(就绪状态取决于操作之间的依赖关系,如a依赖b,那么b就先进入准备就绪状态),然后进入就绪状态的操作的开始执行顺序(非结束执行顺序)由操作之间相对的优先级决定(优先级是操作对象自身的属性)。
操作队列通过设置最大并发操作数(maxConcurrentOperationCount)来控制并发、串行。
NSOperationQueue 为我们提供了两种不同类型的队列:主队列和自定义队列
NSInvocationOperation:
1.不使用queue
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(task1) object:nil];
[op start]; //同步操作
2.使用queue
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(task1) object:nil];
[queue addOperation:op]; //op将在子线程中执行
3.并行执行
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(task1) object:nil];
NSInvocationOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(task2) object:nil];
[queue addOperation:op];
[queue addOperation:op2];
4.串行执行
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(task1) object:nil];
NSInvocationOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(task2) object:nil];
[op2 addDependency:op];
[queue addOperation:op];
[queue addOperation:op2];
NSBlockOperation:
1.没有queue
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"currentThread---1-%@",[NSThread currentThread]); //主线程执行
}];
[op addExecutionBlock:^{
NSLog(@"currentThread---2-%@",[NSThread currentThread]);//子线程执行并且并发
}];
[op addExecutionBlock:^{
NSLog(@"currentThread---3-%@",[NSThread currentThread]);//子线程执行并且并发
}];
[op start];
2.queue中执行:
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"currentThread---1-%@",[NSThread currentThread]);//子线程执行并且并发
}];
[op addExecutionBlock:^{
NSLog(@"currentThread---2-%@",[NSThread currentThread]);//子线程执行并且并发
}];
[op addExecutionBlock:^{
NSLog(@"currentThread---3-%@",[NSThread currentThread]);//子线程执行并且并发
}];
[queue addOperation:op];
3.串行
和NSInvocationOperation一样
- (void)fun{
NSLog(@"1%@",[NSThread currentThread]);
}
NSInvocationOperation *invocation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(fun) object:nil];
NSBlockOperation *blockO = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"2%@",[NSThread currentThread]);
}];
NSOperationQueue *queue = [NSOperationQueue mainQueue];
[queue addOperation:blockO];
[queue addOperation:invocation];
[blockO addDependency:invocation]; 设置执行顺序
addExecutionBlock:操作是并行的。
NSOperation 优先级
NSOperation 提供了queuePriority(优先级)属性,queuePriority属性适用于同一操作队列中的操作,不适用于不同操作队列中的操作。默认情况下,所有新创建的操作对象优先级都是NSOperationQueuePriorityNormal。但是我们可以通过setQueuePriority:方法来改变当前操作在同一队列中的执行优先级
注意:优先级高的并不一定先执行,只是提高了执行的概率。优先级不能取代依赖关系
取消,挂起,继续
注意:NSOperation暂停或者取消只能在开始之前,一旦开始就无法暂停或者取消