10、NSOperation简介

1、 NSOperation介绍
1)是OC语言中基于GCD的面向对象的封装

2)使用起来比GCD更简单(面向对象)

3)提供了一些用GCD不好实现的功能

4)苹果推荐使用,使用NSOperation不用关心线程以及线程的生命周期


2、NSOperation子类
1)NSOperation是一个抽象类

2)NSoperation子类
·NSInvocationOperation
·NSBolockOperation
·自定义Operation

3、NSOperation和NSOperationQueue实现多线程步骤
1)先将需要执行的操作封装到一个NSOperation对象中

2)然后将NSOperation对象添加到NSOperationQueue队列中

3)系统会自动将NSOperationQueue中的NSOperation取出来

4)将取出来的NSOperation封装的操作放到一条新线程中执行


4、NSOperationQueue介绍
1)NSOperation可以调用sgart方法来执行任务,单默认是同步执行的

2)如果将NSOperation添加到NSOperationQueue(操作队列)中,系统会
自动异步执行NSOperation中的操作

3)添加操作到NSOperationQueue中的方法
- (void) addOperation: (NSOperation *) op;
- (void) addOperationWithBlock: (void (^) (void) ) block;


5、子类NSInvocationOperation使用
1)创建NSInvocationOperation对象
- (id) initWithTarget: (id) target selector: (SEL) object: (id) arg;

2)调用start方法开始执行操作
- (void) start;
一旦指向操作,就会调用target的sel方法

注意:
默认情况下,调用了start方法并不会开一条新线程去执行操作,而是在当前线程同步执行操作。
只有将NSOperation放到一个NSOperationQueue中,才会异步执行操作。

6、NSInvocationOperation的使用案例
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
//创建操作
// NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(demo) object:nil];
// NSLog(@"%d",op.isFinished);
// //start方法更新操作的状态 调用main方法
// //不会开启新线程
// [op start]; //不开启新线程
// [op start];
// [op start];
// NSLog(@"%d",op.isFinished);

//创建操作
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(demo) object:nil];
//队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
//把操作添加到队列
[queue addOperation:op];
}

- (void)demo {
NSLog(@"hello %@",[NSThread currentThread]);
}


7、子类NSBlockOperation的使用
1)创建NSBlockOperation对象
+ (id) blockOperationWithBlock: ( void (^) (void) ) block;

2)通过addExecutionBlock:方法添加更多的操作
- (void) addExecutionBlock: (void (^) (void) ) block;

注意:
只要NSBlockOperation封装的操作数>1,就会异步执行操作


8、NSBlockOperation的使用案例
@interface ViewController ()
//全局队列
@property (nonatomic, strong) NSOperationQueue *queue;
@end

@implementation ViewController
//懒加载
- (NSOperationQueue *)queue {
if (_queue == nil) {
_queue = [[NSOperationQueue alloc] init];
}
return _queue;
}

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[self demo5];
}
//演示start
- (void)demo1 {
//创建操作
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"hello %@",[NSThread currentThread]);
}];
//更新op的状态,执行main方法
[op start]; //不会开新线程
}

//把操作添加到队列
- (void)demo2 {
//创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
//创建操作
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"hello %@",[NSThread currentThread]);
}];
//把操作添加到队列中
[queue addOperation:op];
}

- (void)demo3 {
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperationWithBlock:^{
NSLog(@"hello %@",[NSThread currentThread]);

}];
}

//全局队列
- (void)demo4 {
// //并发队列,异步执行
// for (int i = 0; i < 10; i++) {
// [self.queue addOperationWithBlock:^{
// NSLog(@"hello %d %@",i,[NSThread currentThread]);
// }];
// }
}

// 操作的 completionBlock
- (void)demo5 {
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
[NSThread sleepForTimeInterval:2];
NSLog(@"hello %@",[NSThread currentThread]);
}];
//操作完成之后执行
[op setCompletionBlock:^{
NSLog(@"end %@",[NSThread currentThread]);

}];
[self.queue addOperation:op];
}

@end


9、线程间的通信
1)主队列
·添加到主队列的操作,最终都执行在主线程上
·[NSOperationQueue mainQueue]

2)当前队列
·获取当前操作所在的队列
·[NSOperationQueue currentQueue]

3)模拟当前图片下载完成后回归到主线程上
- (void)viewDidLoad {
[super viewDidLoad];
[self.queue addOperationWithBlock:^{
//异步下载图片
NSLog(@"异步下载图片");
//线程间通信,回到主线程更新UI
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
NSLog(@"更新UI");
}];
}];
}






猜你喜欢

转载自blog.csdn.net/daidaishuiping/article/details/80258640