码迷,mamicode.com
首页 > 其他好文 > 详细

NSOperation

时间:2015-09-04 22:22:25      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:

/*------------------------------  NSOperation使用 1.简介  -----------------------------------*/
 
 
 
1.NSoperation (操作)简介:
NSOperation : //本质是 对GCD的封装 .OC语言
 
NSOperation 和GCD的比较:
GCD使用场合:
一些简单的需求,简单的多线程操作 //简单高效
 
NSOperation 使用场合:
各个操作之间有相互依赖关系,操作需要取消/暂停; 需要限制同时执行的线程数量,让线程在某时刻停止/继续等
 
配合使用 NSOperation 和 NSOperationQueue 也可以实现多线程.
 
2. NSOperation 使用:
 
NSOperation : 抽象类,不能直接使用,需要使用其子类.
 
抽象类:定义子类共有的属性和方法. //CAAnimation / CAPropertyAnimation..
 
两个常用的子类:NSInvocationOperation (调用) 和NSBlockOperation;
两者没有本质区别,后者使用block 的形式组织代码,使用相对方便.
 
自定义子类继承自 NSOperation 实现内部相应的方法. //高级方法
 
 
/*----------------------------  NSOperation使用 2.NSOperation ------------------------------*/
 
重点: 1.NSBlockOperation, NSInvocationOperation的简单使用
 
创建 NSInvocationOperation 对象
NSInvocationOperation * op1 = [[NSInvocationOperation alloc]initWithTarget : self selector:@selector (longTimeOperation : )object:@“object:@"op1"];
 
//默认情况下,调用 start 方法之后,不会开启新线程,只会在当前线程执行操作
[op1 start];
 
注意:只有将 NSOperation 放到一个NSOperationQueue 中,才会异步执行操作
 
 
2.创建 NSBlockOperation 对象
NSBlockOperation * op2 = [NSBlockOperation blockOperationWithBlock:^{
 
NSLog(@“下载图片1-—%@“,[NSThread currentThread]);
 
//添加更多操作
[op2 addExecutionBlock:^{
     NSLog(@“下载图片2-—%@“,[NSThread currentThread]);
}];
 
[op2 addExecutionBlock:^{
     NSLog(@“下载图片3-—%@“,[NSThread currentThread]);
}];
 
//只要 NSBlockOperation 中封装的操作数 >1 ,调用start方法之后就会开启多条线程并发执行
 
//如果 NSBlockOperation 中封装的操作数 == 1,调用start 方法之后,不会开启新线程,只会在当前线程执行操作
 
[op2 start];
 
注意:只要 NSBlockOperation 中封装的操作数 > 1 ,就会异步执行这个操作.(将操作添加到NSOperationQueue中或者直接调用start方法都会开启多条线程异步执行)
}]; 
 
/*---------------------------- NSOperation使用 3.NSOperationQueue --------------------------*/
 
重点:将操作添加到队列中:
NSOperation 可以调用 start 方法来执行任务,但默认是同步执行.将NSOperation 添加到NSOperationQueue(操作队列) 中,系统会自动异步执行NSOperationQueue中的操作
 
1.NSOperationQueue(操作队列):
<1> 主队列   主队类是获取来的
[NSOperationQueue mainQueue ]; //获取主队列
添加到”主队列”中的操作,都会放在主线程执行
 
<2> 非主队列   创建而来
[ [NSOperationQueue alloc] init]; //创建非主队列
添加到”非主队列”中的操作,都会放在子线程中执行
 
2.使用: 添加到操作队列中
 
//将操作添加到操作队列里面
//创建 NSInvocationOperation 操作
NSInvocationOperation *op1 = [[NSInvocationOperation  alloc]initWithTarget:self selector : @selector (longTimeOperation :) object : @“op1"];
 
//创建 NSBlockOperation 操作
NSBlockOperation *op2 = [NSBlockOperation  blockOperationWithBlock:^{
     
NSLog(@“下载图片1-—%@“,[NSThread currentThread]);
 
}];
 
 
//1 创建一个NSOperationQueue
 
NSOperationQueue *queue =  [[ NSOperationQueue  alloc] init];
 
// 将操作添加到队列中
[queue  addOperation : op1];
[queue  addOperation : op2];
 
注意:另外一种添加操作到队列中的方法:block
[queue addOperationWithBlock : ^{
      NSLog(@“下载图片5-—%@“,[NSThread currentThread]);
}];
 
很熟练有木有??
 
注意:队列中任务的执行是无序的 
 
/*-------------------------------- NSOperation使用 4.常见用法1 -------------------------------*/
 
重点 : 设置操作依赖. 2.设置最大并发数
 
问题:是否可以让队列中的操作有序执行?
答:可以 在队列之间设置操作依赖就可以
 
1.NSOperation 设置操作依赖: //执行顺序op1 op2 op3
 
//操作op3 依赖于 op2
[op3 addDependency:op2]; op2 先执行
 
//操作op2 依赖于 op1;
[op2 addDependency : op1];  op1 先执行
 
 
 
注意:不能相互依赖
[op1 addDependency : op3]; //错误 会造成循环依赖 如果这样设置的话 op3 先执行 在执行op1  这样就会和上面的起冲突
 
2.NSOperationQueue 设置最大并发数
并发数:同时开启的线程数.
 
//创建操作队列
NSOperationQueue *queue =[  [NSOperationQueue alloc] init ];
 
//设置操作队列的最大并发数
queue.maxConcurrentOperationCount = 3;
[queue setMaxConcurrentOperationCount : 3];
 
/*-------------------------------- NSOperation使用 5.常见用法2 -------------------------------*/
 
重点:1 队列的取消/暂停/恢复 2.线程间通信. 注意问题:为什么要取消/恢复队列? /在什么时候用?
 
1.NSOperationQueue  的取消/暂停/恢复
 
//1.取消操作 op1 取消单个操作
[op1  cancel ];
 
//取消所有操作,不会再恢复
[ queue cancelAllOperations ];
 
//重新开始所有操作
[ queue setSuspended: NO ];
 
问:为什么要取消恢复队列? 在什么时候用?
答:1  为了内存管理,处理内存警告; 
     2  为了用户体验,保证滚定流畅.
 
// 接受到内存警告的时候果断取消队列中的所有操作
-(void)didReceiveMemoryWarning
{
 
     [super didReceiveMemoryWarning ];
       [queue  cancelAlloperations ];  //取消队列中的所有任务(不可恢复)
 
}
 
//开始滚动的时候暂停队列中的任务.
-(void)scrollerViewWillBeginDragging: (UIScrollView *)scrollview
 
{
     [queue  setSuspended : YES]; //暂停队列中的所有任务
}
 
//滚动结束的时候恢复队列中的任务
-(void) scrollerViewDidEndDragging : (UIScrollerView *)scrollerView  willDecelerate : (BOOL) decelerate
{
     [queue setSuspended: NO];  //恢复队列中的所有任务
}
 
2.线程间通信 //子线程下载图片  主线程设置图片
NSOperationQueue *queue = [ [NSOperationQueue alloc] init ];
 
[queue  addOperationWithBlock : ^{
 
//异步下载图片
NSURL * url = [NSURL URLWithString :@“图片地址"];
 
NSData *data = [NSData  dataWithContentsOfURL:url];
 
UIImage *image = [UIImage  imageWithData:data];
=========下载完成=====
 
//2.回到主线程  显示图片
[[ NSOperationQueue mainQueue] addOperationWithBlock:^{
     
self.imageView.image = image;
}];
 
}];
 
 

NSOperation

标签:

原文地址:http://www.cnblogs.com/R-X-L/p/4782436.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!