iOS-多线程之NSOperation
来源:互联网 发布:linux中rpm文件 编辑:程序博客网 时间:2024/05/19 17:57
继之前的NSThread、GCD,今天学习下NSOperation。NSOperation是个抽象类,并不直接实现多线程编程的能力,必须使用它的子类,配合使用NSOperationQueue队列实现多线程编程。
- NSInvocationOperation
- (通过initWithTarget:执行任务) - NSBlockOperation
- (通过block执行任务) - 自定义子类继承自NSOperation,实现内部相应的方法
- (通过重写父类的方法,执行任务)
NSInvocationOperation 的运用
// 通过 NSInvocationOperation 创建任务-(void)NSInvocationOperation { // 创建任务 NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(do_method) object:nil]; // 开始任务 [operation start];}-(void)do_method { NSLog(@"---任务01---%@",[NSThread currentThread]);}
总结:默认主线程执行,不开启新线程
NSBlockOperation 的运用
// 通过 NSBlockOperation 创建任务-(void)NSBlockOperation { NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"---任务01---%@",[NSThread currentThread]); }]; // 只要NSBlockOperation封装的操作数 > 1,就会异步执行操作 // 追加额外的任务 [operation addExecutionBlock:^{ NSLog(@"---任务02---%@",[NSThread currentThread]); }]; // 追加额外的任务 [operation addExecutionBlock:^{ NSLog(@"---任务03---%@",[NSThread currentThread]); }]; // 开始队列任务 [operation start];}
总结:如果任务只有一条,不开启新线程,主线程执行;当添加额外的任务时,会开启新的线程去执行任务
自定义 NSOperation 的运用
需要在自定义的XMOperation文件中重写 - (void)main; 方法// 将需要执行的任务方法main函数中,当外界调用自己实例的start方法时,执行该任务-(void)main { NSLog(@"---我是自定义队列任务---%@",[NSThread currentThread]);}// 自定义 NSOperation-(void)DIYOperation { // 自定义继承自 NSOperation 的任务 XMOperation *operation = [[XMOperation alloc] init]; // 开始任务(去实现自定义类方法中的main函数) [operation start];}
总结:当调用 [operation start] 后执行 - (void)main; 方法
NSOperationQueue 的运用
-(void)operationQueue { // 创建队列 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 通过 NSInvocationOperation 创建任务 NSInvocationOperation *opt = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(do_method) object:nil]; // 通过 NSBlockOperation 创建任务 NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"---任务02---%@",[NSThread currentThread]); }]; // 添加任务到队列中 [queue addOperation:operation]; [queue addOperation:opt]; // 直接向队列中添加任务 [queue addOperationWithBlock:^{ NSLog(@"---任务03---%@",[NSThread currentThread]); }];}
总结:开启多条线程,并且并发执行任务
最大并发数的使用(maxConcurrentOperationCount)
-(void)maxConcurrentOperationCount { // 创建队列 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 确定最大并发数,当并发数为1时,是串行队列 // 当并发数为n(n>1)时,是并发队列,每次并发执行n条任务 queue.maxConcurrentOperationCount = 2; // 添加任务到队列中 [queue addOperationWithBlock:^{ NSLog(@"---任务01---%@",[NSThread currentThread]); }]; [queue addOperationWithBlock:^{ NSLog(@"---任务02---%@",[NSThread currentThread]); }]; [queue addOperationWithBlock:^{ NSLog(@"---任务03---%@",[NSThread currentThread]); }]; [queue addOperationWithBlock:^{ NSLog(@"---任务04---%@",[NSThread currentThread]); }];}
- 图片 01 (最大并发数为2)
- 图片 02 (最大并发数为1)
总结:当最大并发数为1时,开启新线程,但一般只会开启一条,因为此时是串行执行。见图片 01
当最大并发数大于1时(n(n>1)),开启多条线程,并发执行n条任务。见图片 01
对任务添加依赖的运用(addDependency)
// 添加依赖-(void)addDependency { // 创建队列 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 通过 NSBlockOperation 创建任务 NSBlockOperation *opt1 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"---任务01---%@",[NSThread currentThread]); }]; NSBlockOperation *opt2 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"---任务02---%@",[NSThread currentThread]); }]; NSBlockOperation *opt3 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"---任务03---%@",[NSThread currentThread]); }]; NSBlockOperation *opt4 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"---任务04---%@",[NSThread currentThread]); }]; // 添加依赖 [opt3 addDependency:opt4]; // 线程opt3 需要在 opt4 执行完毕后执行 [opt2 addDependency:opt3]; // 线程opt2 需要在 opt3 执行完毕后执行 [opt1 addDependency:opt2]; // 线程opt1 需要在 opt2 执行完毕后执行 // 添加任务到队列中 [queue addOperation:opt1]; [queue addOperation:opt2]; [queue addOperation:opt3]; [queue addOperation:opt4];}
总结:开启新线程,但执行顺序受依赖的影响
为每条任务添加依赖,也可以实现串行队列
队列的状态
- 暂停(suspended = YES) - 执行(suspended = NO)- 取消所有任务 (cancelAllOperations)- 判断是否暂停 (isSuspended)
if (self.queue.isSuspended) { // 队列处于暂停状态 // 恢复队列,继续执行 self.queue.suspended = NO; } else { // 队列处于正常状态 // 暂停(挂起)队列,暂停执行 self.queue.suspended = YES; } // 取消所有队列 [self.queue cancelAllOperations];
线程之间的通信
线程之间的通信模板
// 线程之间的通信-(void)communicateWithOperation { NSOperationQueue *queue = [[NSOperationQueue alloc] init]; [queue addOperationWithBlock:^{ NSLog(@"---子线程任务---%@",[NSThread currentThread]); // 回到主线程执行任务 [[NSOperationQueue mainQueue] addOperationWithBlock:^{ NSLog(@"---主线程任务---%@",[NSThread currentThread]); }]; }];}
利用NSOperationQueue在子线程下载图片,主线程显示图片
// 线程之间的通信实例-(void)communicateWithOperationInstance { // 开辟一个子线程执行图片下载任务 [[[NSOperationQueue alloc] init] addOperationWithBlock:^{ // 图片的网络路径 NSURL *url = [NSURL URLWithString:@"http://xxx.png"]; // 加载图片 NSData *data = [NSData dataWithContentsOfURL:url]; // 生成图片 UIImage *image = [UIImage imageWithData:data]; // 回到主线程,添加图片 [[NSOperationQueue mainQueue] addOperationWithBlock:^{ self.imageView.image = image; }]; }];}
总结:多线程的学习就到这里了,NSThread、GCD、NSOperation 这三条多线程方法在iOS开发中运用还是比较频繁的,其中GCD的功能最多,可以实现单例,延迟执行,多线程遍历,线程群组,线程阻碍等等。对于任务的分段下载,既可以用GCD的群组,也可以用NSOperation的依赖来实现。最后说一句,学习,一定得去敲,得去写,进步才会快
0 0
- iOS多线程之NSOperation
- iOS多线程之NSOperation
- iOS多线程之NSOperation
- ios多线程之NSOperation
- IOS多线程之NSOperation
- iOS多线程之NSOperation
- iOS --- 多线程之NSOperation
- iOS-多线程之NSOperation
- iOS -- 多线程之NSOperation
- iOS多线程之NSOperation
- IOS多线程之NSOperation
- iOS多线程之NSOperation
- ios 多线程之NSOperation
- IOS多线程开发之NSOperation
- iOS多线程之二 NSOperation
- iOS多线程编程之NSOperation
- iOS整理 -- 多线程之 NSOperation
- iOS多线程编程之NSOperation
- 转载--网页性能管理详解
- MySQL备忘录
- VS2010出现如下链接错误:LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
- STM32F4_TIM基本延时(计数原理)
- iOS中四种存储方式
- iOS-多线程之NSOperation
- AppCan4.0:开发者要做有价值的APP
- html (jsp )表单元素总结
- 我的activemq JDBC Master Slave主从和持久化配置过程
- 编程技巧 - 9
- IOS 使用 CAEmitterLayer实现粒子效果
- linux应用程序调试gdb+gdbserver
- 博客地址
- ubuntu下对sd卡 分区和格式化 挂载sd卡