iOS 【Multithreading-线程间通信(NSOperation)/最大并发数/操作依赖/NSOperation优先级】
2016-01-22 21:25
459 查看
// // ViewController.m // 45-NSOperation(NSOperationQueue) // // Created by 王中尧 on 16/1/22. // Copyright © 2016年 黑马. All rights reserved. // #import "ViewController.h" @interface ViewController () @property (weak, nonatomic) IBOutlet UIImageView *imageView; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. } - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { // 使用队列下载图片 线程间通信 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; [queue addOperationWithBlock:^{ NSURL *url = [NSURL URLWithString:@"http://pic14.nipic.com/20110522/7411759_164157418126_2.jpg"]; NSData *data = [NSData dataWithContentsOfURL:url]; UIImage *image = [UIImage imageWithData:data]; // 从 其他线程回到主线程 显示图片方式 // 方法一: // self performSelectorOnMainThread:<#(nonnull SEL)#> withObject:<#(nullable id)#> waitUntilDone:<#(BOOL)#> // 方法二:(GCD) // dispatch_async(dispatch_get_main_queue(), ^{ // <#code#> // }) // 方法三:(队列) [[NSOperationQueue mainQueue] addOperationWithBlock:^{ self.imageView.image = image; }]; }]; } - (void)didReceiveMemoryWarning { // 此方法是要调用其super的 [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. //当系统的内存不足时,UIViewController的didReceiveMemoryWarining 方法会被调用,我们可以在didReceiveMemoryWarining 方法里释放掉部分暂时不用的资源。 // [queue cancelAllOperations]; // 取消队列中的所有任务(不可恢复) // 我们在清理内存的时候就不要干别的事儿了,索性将队列任务全部取消。所以这个方法(cancelAllOperations)一般用在此处(didReceiveMemoryWarning)。 } - (void)download { NSLog(@"download---%@", [NSThread currentThread]); } - (void)baseUse { // 1.创建一个队列(非主队列) NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 2.添加操作到队列中(自动异步执行任务,并发) NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"下载图片1---%@", [NSThread currentThread]); }]; NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"下载图片2---%@", [NSThread currentThread]); }]; [queue addOperation:operation1]; [queue addOperation:operation2]; [queue addOperationWithBlock:^{ NSLog(@"下载图片3---%@", [NSThread currentThread]); }]; // 3个操作并发执行(添加就会执行) } // 最大并发数 - (void)maxCount { // 1.创建一个队列(非主队列)。 // 注意:创建队列(默认是并发队列,如果设置最大并发数为1,也就是同时只能执行一个任务,那么就相当于创建了一个串行队列了) NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 2.设置最大并发(最多同时并发执行3个任务) // 最大并发数默认为-1,意为不受限制。最大并发数也可以设置为0,那么就不会执行任务。 // ★ 这里要注意,是同时并发执行3个任务,关键词在同时,所以说线程可能开了3条,也可能开了4条,这个是不一定的,但是同时并发执行的肯定只有3条线程。而且这里还有一个关键词是最多,所以说可能同时并发2个,不足3个也是可以的。 // 最大并发数是指执行任务的线程最多是3个,但是,处于回收状态的线程不算此列.也就是说,执行任务的时候不只有两个线程,还有处于回收状态的线程 queue.maxConcurrentOperationCount = 3; // 3.添加操作到队列中(自动异步执行任务,并发) // 封装操作:初始化操作对象(operation),然后将 任务 添加到 操作对象 中 NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"下载图片1---%@", [NSThread currentThread]); }]; NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"下载图片2---%@", [NSThread currentThread]); }]; NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"下载图片3---%@", [NSThread currentThread]); }]; // 将 操作 添加到 队列 中去 [queue addOperation:operation1]; [queue addOperation:operation2]; [queue addOperation:operation3]; // 往队列中去添加操作的简便写法(创建操作并添加该操作到队列中去,作用一样,但是简便。也有不足之处:如果别的地方想使用该操作,是拿不到的,因为没有一个指针指向该操作对象。上面的都有类似 *operation1 的指针指向,所以可以拿到他)。 [queue addOperationWithBlock:^{ NSLog(@"下载图片9---%@", [NSThread currentThread]); }]; } // 操作依赖 - (void)qwe { /** 假设有A、B、C三个操作,要求: 1. 3个操作都异步执行() 2. 操作C依赖于操作B 3. 操作B依赖于操作A */ NSBlockOperation *operationA = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"A---%@",[NSThread currentThread]); }]; // 为operationA再添加一个任务(追加任务) // 注意:往操作中 追加的任务 和 该操作 原本就有的任务不一定谁先执行。因为将操作添加到队列中就是自动异步并发执行。 [operationA addExecutionBlock:^{ NSLog(@"AAAAAAA---%@",[NSThread currentThread]); }]; // setCompletionBlock 此方法会在operationA执行后接着执行。 [operationA setCompletionBlock:^{ NSLog(@"A@A@A@"); }]; NSBlockOperation *operationB = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"B---%@",[NSThread currentThread]); }]; NSBlockOperation *operationC = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"C---%@",[NSThread currentThread]); }]; // 设置操作C依赖于操作B,操作B依赖于操作A [operationC addDependency:operationB]; [operationB addDependency:operationA]; NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // queue.maxConcurrentOperationCount = 3; // 最大并发数设置为1则顺序执行了 // 设置完依赖之后,输出的顺序只与依赖有关 [queue addOperation:operationB]; [queue addOperation:operationC]; [queue addOperation:operationA]; <div style="margin-left: 30px;">// 注意:一定要在 操作添加到队列 之前 设置依赖。 </div><div style="margin-left: 30px;">// 提示:任务添加的顺序并不能够决定执行顺序,执行的顺序取决于依赖。使用Operation的目的就是为了让开发人员不再关心线程。</div> } /* (1)设置NSOperation在queue中的优先级,可以改变操作的执⾏优先级 - (NSOperationQueuePriority)queuePriority; - (void)setQueuePriority:(NSOperationQueuePriority)p; (2)优先级的取值 NSOperationQueuePriorityVeryLow = -8L, NSOperationQueuePriorityLow = -4L, NSOperationQueuePriorityNormal = 0, NSOperationQueuePriorityHigh = 4, NSOperationQueuePriorityVeryHigh = 8 说明:优先级高的任务,调用的几率会更大。 */
相关文章推荐
- 总结iOS 多线程学习过程六
- OC笔记 - NSOperation(2015.4.25)
- NSOperation并发编程(转)
- iOS —— NSThread、NSOperation、GCD多线程的优缺点
- Object-C学习笔录(四)多线程编程
- iOS开发系列--并行开发其实很容易
- Oracel一些查看命令
- iOS开发之多线程的五种方法
- NSOperationQueue 方式开启线程
- 如何让NSURLConnection在子线程中运行
- NSOperationQueue和GCD的区别
- iOS多线程编程之NSOperation和NSOperationQueue的使用
- IOS多线程开发之NSOperation
- IOS NSOpertation和NSOperationQueue的使用
- iOS多线程编程(二)NSOperationQueue
- 多线程编程3 - NSOperationQueue
- 使用NSOperation与NSOperationQueue实现多线程
- NSOperationQueue与GCD的使用原则和场景
- iOS线程-NSOperation,NSThread以及GCD
- iOS多线程_获取线程队列执行完毕的信号