iOS开发NSOperation 三:操作依赖和监听以及线程间通信

Posted Hello_IOS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS开发NSOperation 三:操作依赖和监听以及线程间通信相关的知识,希望对你有一定的参考价值。

一:操作依赖和监听

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController
/**
 *  1:NSOperation的使用:1:先创建队列NSOperationQueue:若不创建队列直接封装任务则默认在当前线程中串行执行任务,其队列分为两种主队列和非主队列,主队列和GCD中的主队列一样[NSOperationQueue mainQueue],而alloc init 创建出来的队列,默认具有串行和并发的功能,默认是并发的,可以通过指定最大并发数来确定其是串行队列还是主队列,为0,默认什么都不做,为1默认为串行队列,大于1为并发队列 2:封装任务:用NSOperation的子类,NSBlockOperation,NSInvercation,或是继承NSOperation重写main方法封装任务,(还有快速封装任务:1:[queue addOperationWithBlock:<#^(void)block#>]; 2:还可以在某个任务后追加任务:[op4 addExecutionBlock],当某个操作中的任务数量大于1后,会开启子线程,其子线程有可能是开启的异步线程有可能是主线程还有可能是当前线程 3:还可以添加操作监听:op3.completionBlock,当op3任务执行完毕后,就会进入此block执行任务 4:还可以实现操作依赖:可跨队列依赖,但是不能循环依赖addDependency)3:将操作添加到队列中,[queue addOperation:op1];此方法默认执行了[queue start];
 *
 */
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    //1.创建队列
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    NSOperationQueue *queue2 = [[NSOperationQueue alloc]init];
    
    //2.封装操作
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"1---%@",[NSThread currentThread]);
    }];
    
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"2---%@",[NSThread currentThread]);
    }];
    
    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"3---%@",[NSThread currentThread]);
    }];
    
    NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"4---%@",[NSThread currentThread]);
    }];
    
    //操作监听
    op3.completionBlock = ^{
        NSLog(@"++++客官,来看我吧------%@",[NSThread currentThread]);
    };
    
    [op4 addExecutionBlock:^{
    NSLog(@"5---%@",[NSThread currentThread]);
    }];
    
    [op4 addExecutionBlock:^{
        NSLog(@"6---%@",[NSThread currentThread]);
    }];
    
    [op4 addExecutionBlock:^{
        NSLog(@"7---%@",[NSThread currentThread]);
    }];
    
    
    //添加操作依赖
    //注意点:不能循环依赖
    //可以跨队列依赖
    [op1 addDependency:op4];
//    [op4 addDependency:op1];
    
    [op2 addDependency:op3];
    
    //添加操作到队列
    [queue addOperation:op1];
    [queue addOperation:op2];
    [queue addOperation:op3];
    [queue2 addOperation:op4];
    
}

@end

二:线程间通信

 

#import "ViewController.h"

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end

@implementation ViewController

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [self comBie];
}

-(void)download
{
    
    //http://s15.sinaimg.cn/bmiddle/4c0b78455061c1b7f1d0e
    
    //1.开子线程下载图片
    //1.1 非主队列
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    
    //1.2 封装操作
    NSBlockOperation *download = [NSBlockOperation blockOperationWithBlock:^{
        
        NSURL *url = [NSURL URLWithString:@"http://s15.sinaimg.cn/bmiddle/4c0b78455061c1b7f1d0e"];
        NSData *imageData = [NSData dataWithContentsOfURL:url];
        UIImage *image = [UIImage imageWithData:imageData];
        
        NSLog(@"download---%@",[NSThread currentThread]);
        
        //3.更新UI
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            self.imageView.image = image;
            NSLog(@"UI---%@",[NSThread currentThread]);
        }];
        
    }];
    
    //2.添加操作到队列
    [queue addOperation:download];
}

/*
 1.下载图片1
 2.下载图片2
 3.合并图片
 */
-(void)comBie
{
    //1.创建队列
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    
    __block UIImage *image1;
    __block UIImage *image2;
    //2 封装操作,下载图片1
    NSBlockOperation *download1 = [NSBlockOperation blockOperationWithBlock:^{
        
        NSURL *url = [NSURL URLWithString:@"http://s15.sinaimg.cn/bmiddle/4c0b78455061c1b7f1d0e"];
        NSData *imageData = [NSData dataWithContentsOfURL:url];
        image1 = [UIImage imageWithData:imageData];
        
        NSLog(@"download---%@",[NSThread currentThread]);
        
    }];
    
    //3 封装操作,下载图片2
    NSBlockOperation *download2 = [NSBlockOperation blockOperationWithBlock:^{
        
        NSURL *url = [NSURL URLWithString:@"http://www.027art.com/feizhuliu/UploadFiles_6650/201109/2011091718442835.jpg"];
        NSData *imageData = [NSData dataWithContentsOfURL:url];
        image2 = [UIImage imageWithData:imageData];
        
        NSLog(@"download---%@",[NSThread currentThread]);
        
    }];
    
    //4.封装合并图片的操作
    NSBlockOperation *combie = [NSBlockOperation blockOperationWithBlock:^{
        //4.1 开上下文
        UIGraphicsBeginImageContext(CGSizeMake(200, 200));
        
        //4.2 画图1
        [image1 drawInRect:CGRectMake(0, 0, 100, 200)];
        
        //4.3 画图2
        [image2 drawInRect:CGRectMake(100, 0, 100, 200)];
        
        //4.4 根据上下文得到图片
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        
        //4.5 关闭上下文
        UIGraphicsEndImageContext();
        
        //7.更新UI
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            self.imageView.image = image;
            NSLog(@"UI----%@",[NSThread currentThread]);
        }];
        
    }];
    
    //5.设置依赖关系
    [combie addDependency:download1];
    [combie addDependency:download2];
    
    //6.添加操作到队列中
    [queue addOperation:download2];
    [queue addOperation:download1];
    [queue addOperation:combie];
}
@end

- 2.4 NSOperation实现线程间通信

 

(1)开子线程下载图片

```objc

 //1.创建队列

    NSOperationQueue *queue = [[NSOperationQueue alloc]init];

 

    //2.使用简便方法封装操作并添加到队列中

    [queue addOperationWithBlock:^{

 

        //3.在该block中下载图片

        NSURL *url = [NSURL URLWithString:@"http://news.51sheyuan.com/uploads/allimg/111001/133442IB-2.jpg"];

        NSData *data = [NSData dataWithContentsOfURL:url];

        UIImage *image = [UIImage imageWithData:data];

        NSLog(@"下载图片操作--%@",[NSThread currentThread]);

 

        //4.回到主线程刷新UI

        [[NSOperationQueue mainQueue] addOperationWithBlock:^{

            self.imageView.image = image;

            NSLog(@"刷新UI操作---%@",[NSThread currentThread]);

        }];

    }];

 

```

 

以上是关于iOS开发NSOperation 三:操作依赖和监听以及线程间通信的主要内容,如果未能解决你的问题,请参考以下文章

[iOS开发]NSOperation & NSOperationQueue

iOS多线程开发之NSOperation - 快上车,没时间解释了!

iOS中用GCD和NSOperation多个异步操作的关联

iOS开发之多线程技术——NSOperation篇

iOS开发多线程--(NSOperation/Queue)

iOS开发多线程编程2 - NSOperation