文章分享至个人我的技术博客: https://cainluo.github.io/15019481375874.htmlhtml
以前, 咱们花了小段时间就把GCD
给摸了个底, 知道了GCD
的操做, 不知道你们有没有好好去耍耍, 此次咱们再来说讲, iOS
中的多线程操做.git
NSOperation
, NSOperation
它是基于GCD
的基础进行封装的, 虽然GCD
简单, 可是是C
风格代码, 而NSOperation
的话, 它是Objective-C
风格的代码, 看起来更加的iOS
一些, 代码读起来也是比较更加的直观, 让咱们一块儿去溜溜看吧~github
转载声明:如须要转载该文章, 请联系做者, 而且注明出处, 以及不能擅自修改本文.vim
刚刚咱们提到了NSOperation
是苹果爸爸基于GCD
的封装, 代码风格是Objective-C
, 因此更加简单易懂, 可读性也高.微信
但这里须要注意一下, NSOperation
是须要和NSOperationQueue
配合着来使用的, 这是为啥呢?多线程
由于NSOperation
单独使用的话, 它是属于同步操做, 并不具备开启新线程的功能, 只有配合着NSOperationQueue
才可以实现多线程的操做.ui
咱们都知道NSOperation
是基于GCD
来封装了, 那么使用起来也是和GCD
差很少, 其中的NSOperation
就至关于GCD
中的任务, 而NSOperationQueue
就至关于GCD
中的队列啦.spa
那么使用NSOperation
须要三个步骤:线程
NSOperation
里NSOperationQueue
队列对象NSOperation
对象添加到NSOperationQueue
中, 这样就完成了.在使用的时候, 系统就会自动将NSOperationQueue
中的NSOperation
取出, 而后就在新线程里完成操做.code
在开始撸代码以前, 咱们还得知道一件事, NSOperation
它是属于一个抽象类, 并不能用来封装任务, 那咋办呢?
不要紧NSOperation
这里提供三种方法来实现:
NSInvocationOperation
子类来封装任务NSBlockOperation
子类来封装任务NSOperation
的子类来封装任务, 也就是说, 你能够本身写一个自定义的子类来实现封装任务刚刚咱们也知道了, 单独使用NSOperation
的时候是属于同步执行, 因此下面咱们会了解三种建立的方式.
代码撸起:
- (void)invocationOperation {
NSInvocationOperation *invocationPeration = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(runTheOperation)
object:nil];
[invocationPeration start];
}
- (void)runTheOperation {
NSLog(@"执行任务, 当前的线程为: %@", [NSThread currentThread]);
}
复制代码
2017-08-06 00:23:58.611 NSOperation-Example[961:42623] 执行任务, 当前的线程为: <NSThread: 0x608000066a00>{number = 1, name = main}
复制代码
在结果里, 咱们能够看到在没有使用NSOperationQueue
的时候, 是在主线程中执行, 并无开启新线程.
- (void)blockOperation {
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"执行任务, 当前的线程为: %@", [NSThread currentThread]);
}];
[blockOperation start];
}
复制代码
2017-08-06 00:26:54.808 NSOperation-Example[1002:47303] 执行任务, 当前的线程为: <NSThread: 0x60800006c340>{number = 1, name = main}
复制代码
在结果中, 咱们看到使用NSBlockOperation
也是在主线程中执行任务, 并无开启新线程.
可是在NSBlockOperation
中, 咱们还看到了另一个方法, 这个方法是用来干吗的呢? 来看看代码吧:
- (void)blockOperation {
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"执行任务, 当前的线程为: %@", [NSThread currentThread]);
}];
[blockOperation addExecutionBlock:^{
NSLog(@"执行第二个任务, 当前的线程为: %@", [NSThread currentThread]);
}];
[blockOperation addExecutionBlock:^{
NSLog(@"执行第三个任务, 当前的线程为: %@", [NSThread currentThread]);
}];
[blockOperation addExecutionBlock:^{
NSLog(@"执行第四个任务, 当前的线程为: %@", [NSThread currentThread]);
}];
[blockOperation start];
}
复制代码
2017-08-06 00:30:10.238 NSOperation-Example[1043:51425] 执行任务, 当前的线程为: <NSThread: 0x60000007bac0>{number = 1, name = main}
2017-08-06 00:30:10.238 NSOperation-Example[1043:51592] 执行第四个任务, 当前的线程为: <NSThread: 0x608000267380>{number = 4, name = (null)}
2017-08-06 00:30:10.238 NSOperation-Example[1043:51609] 执行第二个任务, 当前的线程为: <NSThread: 0x600000266c40>{number = 3, name = (null)}
2017-08-06 00:30:10.238 NSOperation-Example[1043:51594] 执行第三个任务, 当前的线程为: <NSThread: 0x608000267200>{number = 5, name = (null)}
复制代码
从打印的结果, 咱们能够看出, 这个方法是能够添加额外的任务, 而且在子线程同步执行.
这里, 咱们建立一个继承于NSOperation
的子类, 暂时想不到有什么好的场景, 这里咱们简单写写就行了.
首先咱们建立一个继承于NSOperation
的子类, 并重写了- (void)main;
方法:
#import "CLOperation.h"
@implementation CLOperation
- (void)main {
for (NSInteger i = 0; i < 5; i++) {
NSLog(@"执行了第%zd次任务, 当前线程为: %@", i, [NSThread currentThread]);
}
}
@end
复制代码
而后回到Controller
, 执行一番:
- (void)customOperation {
CLOperation *clOperation = [[CLOperation alloc] init];
[clOperation start];
}
复制代码
2017-08-06 00:37:32.223 NSOperation-Example[1123:59243] 执行了第0次任务, 当前线程为: <NSThread: 0x60000006c500>{number = 1, name = main}
2017-08-06 00:37:32.223 NSOperation-Example[1123:59243] 执行了第1次任务, 当前线程为: <NSThread: 0x60000006c500>{number = 1, name = main}
2017-08-06 00:37:32.224 NSOperation-Example[1123:59243] 执行了第2次任务, 当前线程为: <NSThread: 0x60000006c500>{number = 1, name = main}
2017-08-06 00:37:32.224 NSOperation-Example[1123:59243] 执行了第3次任务, 当前线程为: <NSThread: 0x60000006c500>{number = 1, name = main}
2017-08-06 00:37:32.224 NSOperation-Example[1123:59243] 执行了第4次任务, 当前线程为: <NSThread: 0x60000006c500>{number = 1, name = main}
复制代码
看到输出的结果, 也是在乎料以内, 也是在主线程中执行, 并无开启新线程.
这一章, 咱们就简单的介绍一下NSOperation
, 而且熟悉一下基本的操做, 回头咱们再把NSOperation
和NSOperationQueue
的配合使用补全.
项目地址: https://github.com/CainRun/iOS-Project-Example/tree/master/NSOperation-Example