这篇文章里我将不过多的谈及理论知识,这些东西会的自然会,不会的,看多了也是云里雾里。下面我讲更多的用代码+注释的方式来讲如何使用NSOperation和NSOperationQueue。
1、NSOperation。是抽象类,不能够直接使用,而是使用子类NSInvocationOperation和NSBlockOperation来实际执行任务。NSOperation本身和多线程是没有任何关系的,她只是封装了一个代码段和数据去实现一个功能。
1.1、NSInvocationOperation,基于一个对象和selector来创建操作。看下面的代码:
1 - (void)invocationOperation {
2
3 NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(startOpration) object:nil];
4 [operation setCompletionBlock:^{
5 NSLog(@"执行完成,是否主线程:%@", [NSThread isMainThread] == 1 ? @"YES" : @"NO");
6 }];
7 [operation start]; //启动任务
8 [operation cancel]; //取消任务
9 [operation isExecuting]; //任务是否在执行
10 [operation isFinished]; //任务是否已经结束
11 }
12
13 - (void)startOpration {
14 NSLog(@"开始执行,是否主线程:%@", [NSThread isMainThread] == 1 ? @"YES" : @"NO");
15 }
首先是创建了一个operation,并给operation添加了一个需要执行的方法:startOpration。其中Line4中的方法将会在operation执行完成后执行,当然不是必须的,如果需要在operation执行完进行一些操作,可以写上这个方法。
下面是执行的结果:
2016-05-06 20:28:19.577 NSOperation[1725:364426] 开始执行,是否主线程:YES
2016-05-06 20:28:19.577 NSOperation[1725:364462] 执行完成,是否主线程:NO
根据上面执行的结果,我们可以发现, startOpration 这个方法是在主线程执行的。至于Line4~Line6是在子线程执行的,则不在今天的讨论内容中,略过。
1.2、NSBlockOperation。相对于NSInvocationOperation,NSBlockOperation则是将selector中需要调用的方法使用Block进行了封装,使用起来更加的方便。关于Block的使用,不明白的同学可以参考我的上一篇博客。
NSBlockOperation对象能够并发的执行一个或多个Block对象,所有相关的Block都执行完成之后,操作才算完成。下面看代码:
1 - (void)blockOperation {
2 //创建一个操作
3 NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
4 NSLog(@"%d,%@,是否主线程:%@", __LINE__, [NSThread currentThread], [NSThread isMainThread] == 1 ? @"YES" : @"NO");
5 }];
6 //通过addExecutionBlock方法添加Block操作
7 [blockOperation addExecutionBlock:^{
8 NSLog(@"%d,%@,是否主线程:%@", __LINE__, [NSThread currentThread], [NSThread isMainThread] == 1 ? @"YES" : @"NO");
9 }];
10 [blockOperation addExecutionBlock:^{
11 NSLog(@"%d,%@,是否主线程:%@", __LINE__, [NSThread currentThread], [NSThread isMainThread] == 1 ? @"YES" : @"NO");
12 }];
13 [blockOperation addExecutionBlock:^{
14 NSLog(@"%d,%@,是否主线程:%@", __LINE__, [NSThread currentThread], [NSThread isMainThread] == 1 ? @"YES" : @"NO");
15 }];
16 [blockOperation addExecutionBlock:^{
17 NSLog(@"%d,%@,是否主线程:%@", __LINE__, [NSThread currentThread], [NSThread isMainThread] == 1 ? @"YES" : @"NO");
18 }];
19 //执行操作
20 [blockOperation start];
21 //上面的几个Block是并发执行的,将会在不同的线程中执行,
22 }
下面是执行的结果:
2016-05-06 20:58:28.585 NSOperation[1754:389977] 48,<NSThread: 0x7f97cad07c30>{number = 1, name = main},是否主线程:YES
2016-05-06 20:58:28.585 NSOperation[1754:390024] 44,<NSThread: 0x7f97cae223c0>{number = 2, name = (null)},是否主线程:NO
2016-05-06 20:58:28.585 NSOperation[1754:390042] 54,<NSThread: 0x7f97cac0eb60>{number = 4, name = (null)},是否主线程:NO
2016-05-06 20:58:28.586 NSOperation[1754:389977] 57,<NSThread: 0x7f97cad07c30>{number = 1, name = main},是否主线程:YES
2016-05-06 20:58:28.585 NSOperation[1754:390030] 51,<NSThread: 0x7f97cad06530