美文网首页
NSOperation简单使用

NSOperation简单使用

作者: 水煮杰尼龟 | 来源:发表于2017-06-10 18:05 被阅读13次

    NSOperation是OC中多线程技术的一种,是对GCD的OC包装.它包含队列(NSOperationQueue)和操作(NSOperation)两个基本要素.

    NSInvocationOperation,NSBlockOperation

    • NSInvocationOperation
      先看看这两个。
    //NSInvocationOperation 没用NSOperationQueue,在主线程调用执行
    -(void)demo
    {
        NSLog(@"---begin");
        NSInvocationOperation *operation=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test) object:nil];
        [operation start];
        NSLog(@"---end");
    }
    -(void)test
    {
        [NSThread sleepForTimeInterval:4];
        for (int i=0; i<3; i++) {
            NSLog(@"---%d---%@",i,[NSThread currentThread]);
        }
    }
    

    编译结果如下:


    NSInvocationOperation.png
    • NSBlockOperation
    NSLog(@"---begin");
        NSBlockOperation *blockOp=[NSBlockOperation blockOperationWithBlock:^{
            [NSThread sleepForTimeInterval:4];
            for (int i=0; i<3; i++) {
                NSLog(@"---%d---%@",i,[NSThread currentThread]);
            }
        }];
        [blockOp start];
        NSLog(@"---end");
    

    编译结果如下:

    NSBlockOperation.png

    从上面两个编译结果可以看出,没有使用NSOperationQueue时,要调用start开始执行,没有开启新的线程,所以---end需要等其执行完再打印。
    NSBlockOperation还有一种使用方法addExecutionBlock:可以添加更多操作。

    NSLog(@"---begin");
        //主线程中执行
        NSBlockOperation *blockOp=[NSBlockOperation blockOperationWithBlock:^{
            for (int i=0; i<3; i++) {
                NSLog(@"---%d---%@",i,[NSThread currentThread]);
            }
        }];
        //主线程和其他线程中执行
        [blockOp addExecutionBlock:^{
            [NSThread sleepForTimeInterval:2];
            for (int i=3; i<6; i++) {
                NSLog(@"---%d---%@",i,[NSThread currentThread]);
            }
        }];
        [blockOp addExecutionBlock:^{
            [NSThread sleepForTimeInterval:3];
            for (int i=6; i<9; i++) {
                NSLog(@"---%d---%@",i,[NSThread currentThread]);
            }
        }];
        [blockOp start];
        NSLog(@"---end");
    

    编译结果如下:

    addExecutionBlock.png

    从我这里的结果来说blockOperationWithBlock里的任务是在主线程执行的,addExecutionBlock里的任务是在主线程和其他线程执行的。而且这里NSBlockOperation时阻塞了主线程的,NSBlockOperation的任务执行完之后才打印---end,NSOperation的start方法默认是同步执行任务.

    NSOperationQueue

    接下来就看看这个了。

    • [queue addOperation:invOp]
    -(void)demo3
    {
        NSLog(@"---begin");
        //队列
        NSOperationQueue *queue=[[NSOperationQueue alloc]init];
        queue.maxConcurrentOperationCount=-1;//最大并发数  1即为串行   默认-1并行
        //任务
        NSInvocationOperation *invOp=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test) object:nil];
        NSBlockOperation *blockOp=[NSBlockOperation blockOperationWithBlock:^{
            [NSThread sleepForTimeInterval:2];
            for (int i=3; i<6; i++) {
                NSLog(@"---%d---%@",i,[NSThread currentThread]);
            }
        }];
        [queue addOperation:invOp];
        [queue addOperation:blockOp];
        NSLog(@"---end");
    }
    -(void)test
    {
        [NSThread sleepForTimeInterval:2];
        for (int i=0; i<3; i++) {
            NSLog(@"---%d---%@",i,[NSThread currentThread]);
        }
    }
    

    编译结果如下:

    NSOperationQueue并发(maxConcurrentOperationCount=-1或大于1).png NSOperationQueue串行(maxConcurrentOperationCount=1).png
    使用NSOperationQueue时,设置maxConcurrentOperationCount最大并发数,默认-1并行,1即为串行。
    • addOperationWithBlock
    NSLog(@"---begin");
        //队列
        NSOperationQueue *queue=[[NSOperationQueue alloc]init];
        //任务
        [queue addOperationWithBlock:^{
            [self test];
        }];
        [queue addOperationWithBlock:^{
            [NSThread sleepForTimeInterval:2];
            for (int i=3; i<6; i++) {
                NSLog(@"---%d---%@",i,[NSThread currentThread]);
            }
        }];
        NSLog(@"---end");
    

    效果一样,使用方法不一样而已。

    • 添加依赖和监听addDependency,completionBlock
    NSLog(@"---begin");
        NSOperationQueue *queue=[[NSOperationQueue alloc]init];
        NSBlockOperation *blockOp=[NSBlockOperation blockOperationWithBlock:^{
            for (int i=0; i<3; i++) {
                NSLog(@"---%d---%@",i,[NSThread currentThread]);
            }
        }];
        NSBlockOperation *blockOp1=[NSBlockOperation blockOperationWithBlock:^{
            for (int i=3; i<6; i++) {
                NSLog(@"---%d---%@",i,[NSThread currentThread]);
            }
        }];
        NSBlockOperation *blockOp2=[NSBlockOperation blockOperationWithBlock:^{
            [NSThread sleepForTimeInterval:2];
            for (int i=6; i<9; i++) {
                NSLog(@"---%d---%@",i,[NSThread currentThread]);
            }
        }];
        //blockOp 依赖于blockOp1,即等blockOp1 执行完再执行 blockOp
        [blockOp addDependency:blockOp1];
        
        [queue addOperation:blockOp];
        [queue addOperation:blockOp1];
        [queue addOperation:blockOp2];
        blockOp.completionBlock=^{
            NSLog(@"---blockOp  over");
        };
        NSLog(@"---end");
    

    编译结果如下:


    依赖和监听.png

    blockOp 依赖于blockOp1,等blockOp1里的任务执行完再执行blockOp的任务,blockOp执行完completionBlock回调打印---blockOp over. blockOp1和blockOp2执行顺序先后是不确定的(异步)。

    • NSOperationQueue的取消
    -(void)demo6
    {
        NSLog(@"---h begin");
        NSOperationQueue *queue=[[NSOperationQueue alloc]init];
        queue.maxConcurrentOperationCount=1;
        NSBlockOperation *blockOp=[NSBlockOperation blockOperationWithBlock:^{
            
            for (int i=0; i<3; i++) {
                NSLog(@"---h %d---%@",i,[NSThread currentThread]);
            }
        }];
        NSBlockOperation *blockOp1=[NSBlockOperation blockOperationWithBlock:^{
            [NSThread sleepForTimeInterval:1];
            for (int i=3; i<6; i++) {
                NSLog(@"---h %d---%@",i,[NSThread currentThread]);
            }
        }];
        NSBlockOperation *blockOp2=[NSBlockOperation blockOperationWithBlock:^{
            [NSThread sleepForTimeInterval:3];
            for (int i=6; i<9; i++) {
                NSLog(@"---h %d---%@",i,[NSThread currentThread]);
            }
        }];
        NSBlockOperation *blockOp3=[NSBlockOperation blockOperationWithBlock:^{
            [NSThread sleepForTimeInterval:4];
            for (int i=9; i<12; i++) {
                NSLog(@"---h %d---%@",i,[NSThread currentThread]);
            }
        }];
        
        [queue addOperation:blockOp];
        [queue addOperation:blockOp1];
        [queue addOperation:blockOp2];
        [queue addOperation:blockOp3];
        self.blockOperation=blockOp3;
        self.queue=queue;
        NSLog(@"---h end");
    }
    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        //[self.blockOperation cancel];
        [self.queue cancelAllOperations];
    }
    

    编译结果如下:

    NSOperationQueue 取消所有cancelAllOperations.png NSOperation 取消单个cancel.png
    • NSOperationQueue的暂停恢复
    -(void)demo6
    {
        NSLog(@"---h begin");
        NSOperationQueue *queue=[[NSOperationQueue alloc]init];
        queue.maxConcurrentOperationCount=1;
        NSBlockOperation *blockOp=[NSBlockOperation blockOperationWithBlock:^{
            
            for (int i=0; i<3; i++) {
                NSLog(@"---h %d---%@",i,[NSThread currentThread]);
            }
        }];
        NSBlockOperation *blockOp1=[NSBlockOperation blockOperationWithBlock:^{
            [NSThread sleepForTimeInterval:1];
            for (int i=3; i<6; i++) {
                NSLog(@"---h %d---%@",i,[NSThread currentThread]);
            }
        }];
        NSBlockOperation *blockOp2=[NSBlockOperation blockOperationWithBlock:^{
            [NSThread sleepForTimeInterval:3];
            for (int i=6; i<9; i++) {
                NSLog(@"---h %d---%@",i,[NSThread currentThread]);
            }
        }];
        NSBlockOperation *blockOp3=[NSBlockOperation blockOperationWithBlock:^{
            [NSThread sleepForTimeInterval:4];
            for (int i=9; i<12; i++) {
                NSLog(@"---h %d---%@",i,[NSThread currentThread]);
            }
        }];
        
        [queue addOperation:blockOp];
        [queue addOperation:blockOp1];
        [queue addOperation:blockOp2];
        [queue addOperation:blockOp3];
        self.blockOperation=blockOp3;
        self.queue=queue;
        NSLog(@"---h end");
    }
    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        self.queue.suspended=!self.queue.suspended;
        if (self.queue.suspended) {
            NSLog(@"---h暂停");
        }else
        {
            NSLog(@"---h恢复");
        }
    }
    

    编译结果如下:

     ![NSOperationQueue的暂停恢复.png](https://img.haomeiwen.com/i3339381/4b450b2aad3becbf.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    

    NSOperationQueue有个suspended属性,当为YES的时候暂停,为NO时执行。当我点击屏幕时打印暂停,打印结果可以看出并没有马上暂停,它会把正在执行的任务完成才暂停。

    ---------------------个人对NSOperation的总结暂时就这么多吧。

    相关文章

      网友评论

          本文标题:NSOperation简单使用

          本文链接:https://www.haomeiwen.com/subject/zpaqqxtx.html