// // ViewController.m // 05-NSOperation // // Created by jerry on 15/9/5. // Copyright (c) 2015年 jerry. All rights reserved. // /** 开发的时候看自己的需求,根据下面的各个优势, GCD---IOS4.0 - 将任务(block)添加到队列(串行/并发(全局))指定执行任务的方法(同步(阻塞)/异步) - 拿到dispatch_get_main_queue()拿到主队列 线程之间的通信 - NSOperation无法做到的,一次性执行、延迟执行、调度组(NSOperation相对复杂) NSOperation--IOS 2.O - 将操作(异步执行)添加到队列(并发/全局) - [NSOperationQueue mainQueue] 主队列,任务添加到主队列,就会在主线程执行。 - 提供了一些GCD不好实现的--最大并发数 - 暂停/继续 也就是挂起操作 - 取消所有的任务 - 依赖关系 */ /** * 小结: * 只要是NSOperation的一个子类就能添加到操作队列 一旦操作添加到队列,就会自动的异步执行 如果没有添加到队列中 而是使用了start方法,他会在当前线程执行操作。(一般不使用) 如果要做线程之间的痛惜你,可以使用[NSOperationQueue mainQueue]拿到主队列,往主队列添加操作更新ui */ #import "ViewController.h" @interface ViewController () // 负责调度所有的操作 全局队列 @property(nonatomic,strong)NSOperationQueue *opQueue; @end @implementation ViewController -(NSOperationQueue *)opQueue { if (_opQueue==nil) { _opQueue = [[NSOperationQueue alloc]init]; } return _opQueue; } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [self dependcy]; } #pragma mark -- 高级操作 // 依赖关系 - (void)dependcy { /** 例子: 1.下载小说的压缩包 2.解压缩 删除压缩包 3.更新ui */ NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"1.下载小说压缩包"); }]; NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"2.解压小说压缩包"); }]; NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"3.删除小说压缩包"); }]; // 执行任务之间的一个依赖关系 // 指定任务之间的依赖关系--依赖关系可以跨队列(可以在子线程,到主线程更新ui) // op2 依赖op1 [op2 addDependency:op1]; // op3 依赖op2 [op3 addDependency:op2]; // 注意点:一定不要出现循环依赖关系, // [op1addDependency:op3]; // waitUntilFinished:类似于GCD的调度组的通知 // YES 是等待线程执行完毕,才会执行后边的代码 // no 是不会等待线程执行完毕,直接执行后边的代码 [self.opQueue addOperations:@[op1,op2] waitUntilFinished:YES]; // 在主线程更新ui [[NSOperationQueue mainQueue] addOperation:op3]; NSLog(@"come here"); } // MARK 取消所有的队列操作 ,他是取消所有队列的操作。 - (IBAction)cancelAll { [self.opQueue cancelAllOperations]; NSLog(@"取消所有的操作"); self.opQueue.suspended = NO; } // 暂停操作 线程挂起。 - (IBAction)pause { // 判断当前队列是否有操作, if (self.opQueue.operationCount == 0) NSLog(@"当前没有任何操作"); return; self.opQueue.suspended = !self.opQueue.suspended; if (self.opQueue.suspended) { NSLog(@"暂停"); }else {NSLog(@"继续");} } // 最大并发数 -(void)opDemo5 { // 设置最大并发数 默认是-1 所以 我们设置1 其实是有两条线程。 self.opQueue.maxConcurrentOperationCount = 2; for (int i = 0; i < 10; i++) { NSOperation *op = [NSBlockOperation blockOperationWithBlock:^{ [NSThread sleepForTimeInterval:2.0]; NSLog(@"----%@-----%d",[NSThread currentThread],i); }]; [self.opQueue addOperation:op]; } } #pragma mark --基本使用 /** * 线程之间的通信 */ -(void)opDemo4 { // 初始化队列 NSOperationQueue *queue = [[NSOperationQueue alloc]init]; [queue addOperationWithBlock:^{ NSLog(@"耗时操作----%@",[NSThread currentThread]); // 在住线程更新ui [[NSOperationQueue mainQueue]addOperationWithBlock:^{ NSLog(@"在主线程更新ui------%@",[NSThread currentThread]); }]; }]; } -(void)opDemo3 { NSOperationQueue *queue = [[NSOperationQueue alloc]init]; for (int i = 0; i < 10; i++) { [queue addOperationWithBlock:^{ NSLog(@"%@---%d",[NSThread currentThread],i); }]; } } -(void)opDemo2 { // 1.队列--- 相当于GCD的并发队列 NSOperationQueue *queue = [[NSOperationQueue alloc]init]; // 主队列 -- 不会开启新线程,相当于GCD里边的主队列 // NSOperationQueue *queue = [NSOperationQueue mainQueue]; // 2.多个操作 for (int i = 0 ; i < 10; i++) { NSBlockOperation *opBlock = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"%@---%d",[NSThread currentThread],i); }]; // 把block操作放到队列里 [queue addOperation:opBlock]; } } -(void)opDemo1 { // 1.初始化一个nsoperation NSOperation *op = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(downloadImg:) object:@"Invocation"]; // // 2.启动---他是在当前线程执行, // [op start]; // 实际操作的时候是放到队列中进行的 NSOperationQueue *queue = [[NSOperationQueue alloc]init]; // 只要把操作添加到队列,就会自动异步执行调度方法。 [queue addOperation:op]; } -(void)downloadImg:(id)obj { NSLog(@"%@----%@",[NSThread currentThread],obj); } @end