多线程编程-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");
}

 

 

 

猜你喜欢

转载自www.cnblogs.com/StevenHuSir/p/iOS_NSOperation.html