zoukankan      html  css  js  c++  java
  • 多线程编程-003-NSOPeration

    NSOPeration  [NSOperationQueue addOperation]

    NSOPeration:将“操作”添加到“队列”。GCD:将任务添加到队列

    NSOPeration抽象类 对GCD面向对象的封装,特点:不能直接使用 目的:定义子类共有的属性和方法.

    子类:NSInvocationOperationNSBlockOperation

     NSThread -> pthread   队列:GCD 并发队列

    NSOperation -> GCD   操作:异步执行任务

    //NSOperation 和  GCD 对比:
     //GCD 在 iOS 4.0 推出,针对多核处理器优化的并发技术,是C语言的
         -将任务(block)添加到队列 (串行、并行、主队列、全局队列),并且要指定任务的同步、异步;
         -线程间的通讯 dispatch_get_main_queue()
         -提供了一些  NSOperation 不具备的功能:
           一次执行、 -延迟执行  、-调度组(NSoperation 也可以做到,但有点儿麻烦)
    // NSOperation 在 iOS 2.0; 苹果推出了GCD后,对NSOperation 进行了重写
         -将操作[异步执行的任务添加到并发队列],就会立刻异步执行
         -提供了一些 GCD实现起来比较麻烦的功能 【下载】
           -最大并发数
           -队列的暂停、继续
           -取消所有线程
           -线程依赖(线程A 的执行 必须依赖线程B)(GCD 同步实现!)

    NSInvocationOperation//将操作添加到队列 

        NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downImage:) object:@"Invocation"];
        //会在当前线程执行调度方法
        //[op start];主线程
        //队列
        NSOperationQueue * q = [[NSOperationQueue alloc] init];
        //将操作添加到队列--会自动异步执行调度方法
        [q addOperation:op ];//downImage为子线程

    NSBlockOperation//将操作添加到队列  

     //1.队列
        NSOperationQueue * q = [[NSOperationQueue alloc] init];
        for (int i = 0; i<10; i++) {
            NSBlockOperation * op = [NSBlockOperation blockOperationWithBlock:^{
                NSLog(@"---%@ -- %d",[NSThread currentThread],i);//执行顺序和开线程数不固定
            }];
            //操作添加到队列
            [q addOperation:op];
        }
          简便方法:
              NSOperationQueue * q = [[NSOperationQueue alloc] init];
        for (int i = 0; i<10; i++) {
            [q addOperationWithBlock:^{
                NSLog(@"---%@ -- %d",[NSThread currentThread],i);
            }];
        }

    ③全局队列

    @property (nonatomic, strong) NSOperationQueue * opQueue ;//直接添加任务
        for (int i = 0; i<10; i++) {
            [self.opQueue addOperationWithBlock:^{
                NSLog(@"---%@ -- %d",[NSThread currentThread],i);
            }];
        }
        //blockOperation
        NSBlockOperation * op1 = [NSBlockOperation blockOperationWithBlock:^{
             NSLog(@"---BlockOperation%@ -- %d",[NSThread currentThread],100);
        }];
        [self.opQueue addOperation:op1];
        //invocation
        NSInvocationOperation * op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downImage:) object:@(101)];
        [self.opQueue addOperation:op2];

    回归主线程

         [self.opQueue addOperationWithBlock:^{
            NSLog(@"%@",[NSThread currentThread]);
            //主线程
            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                NSLog(@"Main Thread %@",[NSThread currentThread]);
            }];
        }];

    设置最大并发数(maxConcurrentOPerationCount)

    //设置同时最大的并发操作数量
        self.opQueue.maxConcurrentOperationCount = 2;//一次最多开两个
        //线程的销毁原理 : A,B,C; 当A使用完之后,先把A回收到线程池,此时无法使用A,所以需要新开启一个线程 
        //20 文件? 20 线程?   //Wifi : 5-6   //流量:2-3
           for (int i = 0; i<20; i++) {
            [self.opQueue addOperationWithBlock:^{
                [NSThread sleepForTimeInterval:1.0];
                NSLog(@"---%@ -- %d",[NSThread currentThread],i);
            }];
        }

    设置队列的暂停和继续(suspended)

    //当挂起队列的时候,正在执行的操作是不被挂起!就绪状态的队列才会被挂起
    //suspended : 决定队列的暂停和继续
    operationCount: 队列中的操作数
    - (IBAction)pause:(id)sender {
        //判断队列是否挂起
        if (self.opQueue.isSuspended) {
            NSLog(@"继续 %tu",self.opQueue.operationCount);
            self.opQueue.suspended = NO;
        }else {
            NSLog(@"暂停 %tu",self.opQueue.operationCount);
            self.opQueue.suspended = YES;
        }
    }

    ⑦取消所有操作(cancelAllOperations)

     - (IBAction)cancelAll:(id)sender {
        NSLog(@"取消所有操作!");
        [self.opQueue cancelAllOperations];//此时点击 暂停、继续无法响应 :销毁所有任务 operationCount=0
        //必须重新添加任务才可以使用暂停和继续
    }

    ⑧提供依赖关系(addDependency)

    - (void)dependency {
        /**
         * 下载、解压、通知用户
         */
        //1.下载
        NSBlockOperation * op1 = [NSBlockOperation blockOperationWithBlock:^{
            [NSThread sleepForTimeInterval:3.0];
            NSLog(@"下载--%@ ",[NSThread currentThread]);
        }];
        //2.解压
        NSBlockOperation * op2 = [NSBlockOperation blockOperationWithBlock:^{
            NSLog(@"解压--%@ ",[NSThread currentThread]);
        }];
        //3.通知用户
        NSBlockOperation * op3 = [NSBlockOperation blockOperationWithBlock:^{
            NSLog(@"通知用户--%@ ",[NSThread currentThread]);
        }];
        NSLog(@"Come here");
        //NSOperation 提供依赖关系
        [op2 addDependency:op1];
        [op3 addDependency:op2];
        //[op1 addDependency:op3];//循环依赖 此时队列不执行工作,也不会崩溃
        //添加队列
        [self.opQueue addOperations:@[op1,op2] waitUntilFinished:YES];// YES在所有任务都完成后才会走Come here.
        //在主线程上通知用户
        [[NSOperationQueue mainQueue] addOperation:op3];
        NSLog(@"Come here");
    }

     

     

     

  • 相关阅读:
    App集成支付宝
    关于Objective-c和Java下DES加密保持一致的方式
    Android开发规范
    android 屏幕适配问题
    Android AES加密算法及其实现
    linux文件系统调用(1)---mount
    Java(Android)解析KML文件
    【Akka】在并发程序中使用Future
    函数指针问题,求解答
    android旋转动画的两种实现方式
  • 原文地址:https://www.cnblogs.com/StevenHuSir/p/iOS_NSOperation.html
Copyright © 2011-2022 走看看