iOS开发之多线程-- NSOperation使用简介(个人笔记)
2015-09-06 12:47
423 查看
NSOperation使用简介
1.操作 NSOperation
和操作队列 NSOperationQueue!
{
1.NSOperation(操作)简介:
NSOperation: //
本质是对 GCD 的封装, OC
语言.
NSOperation
和 GCD
的比较:
GCD使用场合:
一些简单的需求,简单的多线程操作.
//简单高效
NSOperation使用场合:
各个操作之间有依赖关系,操作需要取消/暂停;需要限制同时执行的线程数量,让线程在某时刻停止/继续等.
配合使用 NSOperation和 NSOperationQueue
也可以实现多线程.
2.NSOperation使用:
NSOperation:
抽象类,不能直接使用,需要使用其子类.
抽象类:定义子类共有的属性和方法.//
CAAnimation/CAPropertyAnimation...
两个常用子类: NSInvocationOperation(调用)
和 NSBlockOperation(块);
两者没有本质区别,后者使用 Block
的形式组织代码,使用相对方便.
自定义子类继承自 NSOperation,实现内部相应的方法.
// 高级用法
}
2.NSBlockOperation, NSInvocationOperation的简单使用.
{
1.
创建 NSInvocationOperation 对象
//
创建 NSInvocationOperation
NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(longTimeOperation:)
object:@"op1"];
//默认情况下,调用 start
方法之后,不会开启新线程,只会在当前线程执行操作.
[op1 start];
注意:只有将 NSOperation
放到一个 NSOperationQueue
中,才会异步执行操作.
2.
创建 NSBlockOperation 对象
//
创建 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方法都会开启多条线程异步执行).
}
3.将操作添加到队列中;
{
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];
// 2.将操作添加到队列中.
[queue addOperation:op1];
[queue addOperation:op2];
注意:另外一种添加操作到队列中的方法: block
[queue addOperationWithBlock:^{
NSLog(@"下载图片5---%@",[NSThread
currentThread]);
}];
推荐使用: block
// 简单.
自己哪个使用熟练就用哪个.
注意:队列中任务的执行是无序的.
}
4.常见用法
1.设置操作依赖.
2.设置最大并发数.
{
问题:是否可以让队列中的操作有序执行?
回答上问题:
能,设置操作依赖.
1.NSOperation设置操作依赖:
// 执行顺序: op1,op2,op3;
//
操作op3依赖于操作op2;
[op3 addDependency:op2];
//
操作op2依赖于操作op1;
[op2 addDependency:op1];
注意:不能相互依赖.
2.NSOperationQueue设置最大并发数.
并发数:同时开启的线程数.
//
创建操作队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
//
设置操作队列的最大并发数
queue.maxConcurrentOperationCount =
3;
[queue setMaxConcurrentOperationCount:3];
}
1.队列的取消/暂停/恢复
2.线程间通信.
注意问题:为毛要取消/恢复队列?
在什么时候用?
{
1.NSOperationQueue
的取消/暂停/恢复
//
取消操作 op1. 取消单个操作.
[op1 cancel];
//
取消所有操作,不会再次恢复
[queue cancelAllOperations];
//
暂停所有操作;注意,已经开始的操作不会暂停.
[queue setSuspended:YES];
//
重新开始所有操作
[queue setSuspended:NO];
问:为毛要取消恢复队列?
在什么时候用?
答:1.为了内存管理,处理内存警告;
2.为了用户体验,保证滚动流畅.
//
接收到内存警告的时候果断取消队列中的所有操作
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
[queue cancelAllOperations];
// 取消队列中的所有任务(不可恢复)
}
//
开始滚动的时候暂停队列中的任务.
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
[queue setSuspended:YES];
// 暂停队列中的所有任务
}
//
滚动结束的时候恢复队列中的任务.
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
[queue setSuspended:NO];
// 恢复队列中的所有任务
}
2.线程间通信
// 子线程下载图片,主线程设置图片.
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperationWithBlock:^{
// 1.异步下载图片
NSURL *url = [NSURL URLWithString:@"http://d.hiphotos.baidu.com/image/pic/item/37d3d539b6003af3290eaf5d362ac65c1038b652.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
// 2.回到主线程,显示图片
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.imageView.image = image;
}];
}];
}
// 定义一个全局的队列属性.方便在任何方法中都可以使用这个Queue
@property (nonatomic,strong) NSOperationQueue *queue;
// UI 控件用 weak
和 Strong 都没有问题.
// 在开发中,基本会见到所有的UI控件都是用 Strong来做的.
// UI控件一般不要用懒加载的方式加载.UI控件与用户是对应的.UI控件之外的,能用懒加载就用懒加载.
@property (nonatomic,strong) UIButton *button;
// 设置最大并发数.最多同时只能开启6条线程.
[_queue setMaxConcurrentOperationCount:6];
// 这里直接在Block
中使用 self 会造成循环引用. Block使用的注意点之一:循环引用.
// __weak typeof(self) wself = self; wself
就是 self 的弱引用写法.
// GCD中的任务都是封装在Block中,如果GCD中的Block中出现了
self,会造成循环引用吗?
//
// dispatch_async(dispatch_get_main_queue(), ^{
// [self test];
// }); 会造成循环引用吗?
不会造成循环引用,因为 self
对这个Block 没有强引用.
// 创建操作
__weak typeof(self) wself =
self;
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
// Block中出现self .Block
对 self
是强引用.
[wself test];
}];
// 将操作添加到队列中.
// self.queue 对 op
就是强引用.
[self.queue addOperation:op];
1.操作 NSOperation
和操作队列 NSOperationQueue!
{
1.NSOperation(操作)简介:
NSOperation: //
本质是对 GCD 的封装, OC
语言.
NSOperation
和 GCD
的比较:
GCD使用场合:
一些简单的需求,简单的多线程操作.
//简单高效
NSOperation使用场合:
各个操作之间有依赖关系,操作需要取消/暂停;需要限制同时执行的线程数量,让线程在某时刻停止/继续等.
配合使用 NSOperation和 NSOperationQueue
也可以实现多线程.
2.NSOperation使用:
NSOperation:
抽象类,不能直接使用,需要使用其子类.
抽象类:定义子类共有的属性和方法.//
CAAnimation/CAPropertyAnimation...
两个常用子类: NSInvocationOperation(调用)
和 NSBlockOperation(块);
两者没有本质区别,后者使用 Block
的形式组织代码,使用相对方便.
自定义子类继承自 NSOperation,实现内部相应的方法.
// 高级用法
}
2.NSBlockOperation, NSInvocationOperation的简单使用.
{
1.
创建 NSInvocationOperation 对象
//
创建 NSInvocationOperation
NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(longTimeOperation:)
object:@"op1"];
//默认情况下,调用 start
方法之后,不会开启新线程,只会在当前线程执行操作.
[op1 start];
注意:只有将 NSOperation
放到一个 NSOperationQueue
中,才会异步执行操作.
2.
创建 NSBlockOperation 对象
//
创建 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方法都会开启多条线程异步执行).
}
3.将操作添加到队列中;
{
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];
// 2.将操作添加到队列中.
[queue addOperation:op1];
[queue addOperation:op2];
注意:另外一种添加操作到队列中的方法: block
[queue addOperationWithBlock:^{
NSLog(@"下载图片5---%@",[NSThread
currentThread]);
}];
推荐使用: block
// 简单.
自己哪个使用熟练就用哪个.
注意:队列中任务的执行是无序的.
}
4.常见用法
1.设置操作依赖.
2.设置最大并发数.
{
问题:是否可以让队列中的操作有序执行?
回答上问题:
能,设置操作依赖.
1.NSOperation设置操作依赖:
// 执行顺序: op1,op2,op3;
//
操作op3依赖于操作op2;
[op3 addDependency:op2];
//
操作op2依赖于操作op1;
[op2 addDependency:op1];
注意:不能相互依赖.
2.NSOperationQueue设置最大并发数.
并发数:同时开启的线程数.
//
创建操作队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
//
设置操作队列的最大并发数
queue.maxConcurrentOperationCount =
3;
[queue setMaxConcurrentOperationCount:3];
}
1.队列的取消/暂停/恢复
2.线程间通信.
注意问题:为毛要取消/恢复队列?
在什么时候用?
{
1.NSOperationQueue
的取消/暂停/恢复
//
取消操作 op1. 取消单个操作.
[op1 cancel];
//
取消所有操作,不会再次恢复
[queue cancelAllOperations];
//
暂停所有操作;注意,已经开始的操作不会暂停.
[queue setSuspended:YES];
//
重新开始所有操作
[queue setSuspended:NO];
问:为毛要取消恢复队列?
在什么时候用?
答:1.为了内存管理,处理内存警告;
2.为了用户体验,保证滚动流畅.
//
接收到内存警告的时候果断取消队列中的所有操作
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
[queue cancelAllOperations];
// 取消队列中的所有任务(不可恢复)
}
//
开始滚动的时候暂停队列中的任务.
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
[queue setSuspended:YES];
// 暂停队列中的所有任务
}
//
滚动结束的时候恢复队列中的任务.
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
[queue setSuspended:NO];
// 恢复队列中的所有任务
}
2.线程间通信
// 子线程下载图片,主线程设置图片.
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperationWithBlock:^{
// 1.异步下载图片
NSURL *url = [NSURL URLWithString:@"http://d.hiphotos.baidu.com/image/pic/item/37d3d539b6003af3290eaf5d362ac65c1038b652.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
// 2.回到主线程,显示图片
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.imageView.image = image;
}];
}];
}
// 定义一个全局的队列属性.方便在任何方法中都可以使用这个Queue
@property (nonatomic,strong) NSOperationQueue *queue;
// UI 控件用 weak
和 Strong 都没有问题.
// 在开发中,基本会见到所有的UI控件都是用 Strong来做的.
// UI控件一般不要用懒加载的方式加载.UI控件与用户是对应的.UI控件之外的,能用懒加载就用懒加载.
@property (nonatomic,strong) UIButton *button;
// 设置最大并发数.最多同时只能开启6条线程.
[_queue setMaxConcurrentOperationCount:6];
// 这里直接在Block
中使用 self 会造成循环引用. Block使用的注意点之一:循环引用.
// __weak typeof(self) wself = self; wself
就是 self 的弱引用写法.
// GCD中的任务都是封装在Block中,如果GCD中的Block中出现了
self,会造成循环引用吗?
//
// dispatch_async(dispatch_get_main_queue(), ^{
// [self test];
// }); 会造成循环引用吗?
不会造成循环引用,因为 self
对这个Block 没有强引用.
// 创建操作
__weak typeof(self) wself =
self;
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
// Block中出现self .Block
对 self
是强引用.
[wself test];
}];
// 将操作添加到队列中.
// self.queue 对 op
就是强引用.
[self.queue addOperation:op];
相关文章推荐
- 『iOS/Obj-C』V2EX iOS 客户端源码读书笔记
- iOS时间戳与标准时间转换
- iOS: El Capitan Beta 下 Xcode6.4 不显示Scheme菜单
- iOS - 正则表达式判断邮箱,身份证,手机,车牌号...验证是否正确
- 在iOS中修改状态栏字体的颜色
- iOS textField详细解析(转)
- iOS使用Charles(青花瓷)抓包并篡改返回数据图文详解
- iOS 高斯模糊效果
- iOS各种权限判断(相机,相册,定位,录音)
- IOS Block使用(一)
- 转战IOS之: tableview 选中一行后,不显示选中颜色的方法
- IOS版大转盘
- iOS runtime学习
- iOS 属性中strong,weak,assign,retain,copy等特性
- iOS Label文字分段颜色
- iOS-应用管理 用cell实现,前面那个用xib实现
- 【iOS】View实现透明度渐变和颜色渐变
- iOS学习之XMPP注册用户
- iOS 颜色制作背景图片
- RACSignal的Subscription深入分析