玩转iOS开发:iOS中的NSOperation开发(一)

·  阅读 636

文章分享至我的个人技术博客: https://cainluo.github.io/15019481375874.html


之前, 我们花了小段时间就把GCD给摸了个底, 知道了GCD的操作, 不知道大家有没有好好去耍耍, 这次我们再来讲讲, iOS中的多线程操作.

NSOperation, NSOperation它是基于GCD的基础进行封装的, 虽然GCD简单, 但是是C风格代码, 而NSOperation的话, 它是Objective-C风格的代码, 看起来更加的iOS一些, 代码读起来也是比较更加的直观, 让我们一起去溜溜看吧~

转载声明:如需要转载该文章, 请联系作者, 并且注明出处, 以及不能擅自修改本文.


NSOperation简介

刚刚我们提到了NSOperation是苹果爸爸基于GCD的封装, 代码风格是Objective-C, 所以更加简单易懂, 可读性也高.

但这里需要注意一下, NSOperation是需要和NSOperationQueue配合着来使用的, 这是为啥呢?

因为NSOperation单独使用的话, 它是属于同步操作, 并不具有开启新线程的功能, 只有配合着NSOperationQueue才能够实现多线程的操作.

我们都知道NSOperation是基于GCD来封装了, 那么使用起来也是和GCD差不多, 其中的NSOperation就相当于GCD中的任务, 而NSOperationQueue就相当于GCD中的队列啦.

那么使用NSOperation需要三个步骤:

  • 创建任务: 这里我们需要把执行的任务丢到NSOperation
  • 创建队列: 创建NSOperationQueue队列对象
  • 添加任务到队列中: 最后将NSOperation对象添加到NSOperationQueue中, 这样就完成了.

在使用的时候, 系统就会自动将NSOperationQueue中的NSOperation取出, 然后就在新线程里完成操作.


NSOperation和NSOperationQueue的基本使用

在开始撸代码之前, 我们还得知道一件事, NSOperation它是属于一个抽象类, 并不能用来封装任务, 那咋办呢?

没关系NSOperation这里提供三种方法来实现:

  • 使用NSInvocationOperation子类来封装任务
  • 使用NSBlockOperation子类来封装任务
  • 使用继承于NSOperation的子类来封装任务, 也就是说, 你可以自己写一个自定义的子类来实现封装任务

刚刚我们也知道了, 单独使用NSOperation的时候是属于同步执行, 所以下面我们会了解三种创建的方式.

NSInvocationOperation

代码撸起:

- (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的时候, 是在主线程中执行, 并没有开启新线程.

NSBlockOperation

- (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的子类, 暂时想不到有什么好的场景, 这里我们简单写写就好了.

首先我们创建一个继承于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, 并且熟悉一下基本的操作, 回头我们再把NSOperationNSOperationQueue的配合使用补全.


工程地址

项目地址: https://github.com/CainRun/iOS-Project-Example/tree/master/NSOperation-Example


最后

码字很费脑, 看官赏点饭钱可好

微信

支付宝

分类:
iOS
标签:
分类:
iOS
标签: