NSOperation需要配合NSOperationQueue来实现多线程。因为默认情况下,NSOperation单独使用时系统同步执行操作,并没有开辟新线程的能力,只有配合NSOperationQueue才能实现异步执行。
NSOperation实现多线程的使用步骤分为三步:
- 创建任务:先将需要执行的操作封装到一个NSOperation对象中。
- 创建队列:创建NSOperationQueue对象。
- 将任务加入到队列中:然后将NSOperation对象添加到NSOperationQueue中。
NSOperation是个抽象类,并不能封装任务。我们只有使用它的子类来封装任务。我们有三种方式来封装任务。
- 使用子类NSInvocationOperation
- 使用子类NSBlockOperation
- 定义继承自NSOperation的子类,通过实现内部相应的方法来封装任务。
- (void)addOperationToQueue { // 1.创建队列 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 2. 创建操作 // 创建NSInvocationOperation NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run) object:nil]; // 创建NSBlockOperation NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{ for (int i = 0; i < 2; ++i) { NSLog(@"1-----%@", [NSThread currentThread]); } }]; // 3. 添加操作到队列中:addOperation: [queue addOperation:op1]; // [op1 start] [queue addOperation:op2]; // [op2 start] } - (void)run { for (int i = 0; i < 2; ++i) { NSLog(@"2-----%@", [NSThread currentThread]); } }
-
1 2 1 2 开启新线程 并发执行
-
- (void)addOperationWithBlockToQueue { // 1. 创建队列 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 2. 添加操作到队列中:addOperationWithBlock: [queue addOperationWithBlock:^{ for (int i = 0; i < 2; ++i) { NSLog(@"-----%@", [NSThread currentThread]); } }]; }
-
开辟新线程
-
串行并行的关键
-
这里有个关键参数
maxConcurrentOperationCount
,叫做最大并发数。- 最大并发数:
maxConcurrentOperationCount
maxConcurrentOperationCount
默认情况下为-1,表示不进行限制,默认为并发执行。- 当
maxConcurrentOperationCount
为1时,进行串行执行。 - 当
maxConcurrentOperationCount
大于1时,进行并发执行,当然这个值不应超过系统限制,即使自己设置一个很大的值,系统也会自动调整。
- (void)opetationQueue { // 创建队列 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 设置最大并发操作数 // queue.maxConcurrentOperationCount = 2; queue.maxConcurrentOperationCount = 1; // 就变成了串行队列 // 添加操作 [queue addOperationWithBlock:^{ NSLog(@"1-----%@", [NSThread currentThread]); [NSThread sleepForTimeInterval:0.01]; }]; [queue addOperationWithBlock:^{ NSLog(@"2-----%@", [NSThread currentThread]); [NSThread sleepForTimeInterval:0.01]; }]; [queue addOperationWithBlock:^{ NSLog(@"3-----%@", [NSThread currentThread]); [NSThread sleepForTimeInterval:0.01]; }]; [queue addOperationWithBlock:^{ NSLog(@"4-----%@", [NSThread currentThread]); [NSThread sleepForTimeInterval:0.01]; }]; [queue addOperationWithBlock:^{ NSLog(@"5-----%@", [NSThread currentThread]); [NSThread sleepForTimeInterval:0.01]; }]; [queue addOperationWithBlock:^{ NSLog(@"6-----%@", [NSThread currentThread]); [NSThread sleepForTimeInterval:0.01]; }]; }
- 最大并发数:
-
依赖关系
-
- (void)addDependency { NSOperationQueue *queue = [[NSOperationQueue alloc] init]; NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"1-----%@", [NSThread currentThread]); }]; NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"2-----%@", [NSThread currentThread]); }]; [op2 addDependency:op1]; // 让op2 依赖于 op1,则先执行op1,在执行op2 [queue addOperation:op1]; [queue addOperation:op2]; }
- (void)cancel;
NSOperation提供的方法,可取消单个操作- (void)cancelAllOperations;
NSOperationQueue提供的方法,可以取消队列的所有操作- (void)setSuspended:(BOOL)b;
可设置任务的暂停和恢复,YES代表暂停队列,NO代表恢复队列- (BOOL)isSuspended;
判断暂停状态注意:
- 这里的暂停和取消并不代表可以将当前的操作立即取消,而是当当前的操作执行完毕之后不再执行新的操作。
- 暂停和取消的区别就在于:暂停操作之后还可以恢复操作,继续向下执行;而取消操作之后,所有的操作就清空了,无法再接着执行剩下的操作。