• 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]);

            }];

        }];

    ```

  • 相关阅读:
    开始Flask项目
    夜间模式的开启与关闭,父模板的制作
    从首页问答标题到问答详情页
    首页列表显示全部问答,完成问答详情页布局
    制作首页的显示列表
    发布功能完成
    登录之后更新导航
    完成登录功能,用session记住用户名
    完成注册功能
    通过用户模型,对数据库进行增删改查操作
  • 原文地址:https://www.cnblogs.com/cqb-learner/p/5854756.html
Copyright © 2020-2023  润新知