An operation object is an instance of the NSOperation class (in the Foundation framework) that you use to encapsulate work you want your application to perform. The NSOperation class itself is an abstract base class that must be subclassed in order to do any useful work.
NSOperation本身是一个抽象基类,如果要使用的时候应该先继承它而不能直接去实例化一个NSOperation。
Foundation framework提供两个子类,NSInvocationOperation和NSBlockOperation。NSInvocationOperation不需要再继承才能使用,可以方便我们以现有的方法来初始化一个operation。NSBlockOperation方便我们通过block初始化operation。
NSOperation特征:
-
NSOperation之间可以建立依赖关系
-
可以改变operation的优先级
-
能够通过取消操作停止operation
-
有可选的operation block,当主任务完成后
-
KVO监听状态
NSInvocationOperation & NSBlockOperation例子
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.operation = [self taskWithData:@"just test"];
[self.operation start];
NSBlockOperation *blockTest = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"block is comeing");
}];
[blockTest addExecutionBlock:^{
NSLog(@"blocke 2 is coming");
}];
[blockTest addExecutionBlock:^{
NSLog(@"blocke 3 is coming");
}];
[blockTest start];}
- (NSOperation *)taskWithData:(id)data{
NSInvocationOperation *invoTest = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(handleData:) object:data];
return invoTest;
}
- (void)handleData:(id) data
{
NSLog(@"my data");
NSLog(@"%@", data);
}
自定义的NSOperation
至少要实现两个方法:
- A custom initialization method(初始化的方法)
- main
简单实现代码:
@implementation MyOperation
- (instancetype)initWithData:(id) data
{
if (self = [super init]) {
self.myData = data;
[self completeOperation];
}
return self;
}
- (void)main
{
@try {
NSLog(@"my operation is coming");
NSLog(@"%@", _myData);
}
@catch (NSException *exception) {
NSLog(@"%@", exception);
}
@finally {
NSLog(@"finally");
}
}
@end
在ViewController里面实例化
MyOperation *myOperation = [[MyOperation alloc] initWithData:@"my opeation"];
[myOperation start];
并发的NSOperation需要实现以下方法:
- (BOOL)isConcurrent
{
return YES;
}
- (BOOL)isExecuting {
return executing;
}
- (BOOL)isFinished {
return finished;
}
- (void)start{
if([self isCancelled])
{
[self willChangeValueForKey:@"isFinished"];
finished = YES;
[self didChangeValueForKey:@"isFinished"];
return;
}
[self willChangeValueForKey:@"isExecuting"];
[NSThread detachNewThreadSelector:@selector(main) toTarget:self withObject:nil];
executing = YES;
[self didChangeValueForKey:@"isExecuting"];
}
- (void)completeOperation {
[self willChangeValueForKey:@"isFinished"];
[self willChangeValueForKey:@"isExecuting"];
executing = NO;
finished = YES;
[self didChangeValueForKey:@"isExecuting"];
[self didChangeValueForKey:@"isFinished"];
}
Operation中支持KVO的属性
isCancelled
isConcurrent
isExecuting
isFinished
isReady
dependencies
queuePriority
completionBlock
NSOperationQueue
两种初始化的方法:
NSOperationQueue *myQueue1 = [[NSOperationQueue alloc] init];
NSOperationQueue *myQueue2 = [NSOperationQueue mainQueue];//mainQueue
[myQueue1 addOperation:myOperation];
[myQueue1 addOperation:self.operation];
[myQueue1 addOperation:blockTest];
- NSOperationQueue有优先级的概念,因此是不支持FIFO的
- NSOperationQueue是并发执行的,但是可以通过maxConcurrentOperationCount来设置并发的数量
NSOperation相对于GCD的优势
-
可以取消某个操作。调用cancel方法可以取消操作,但是开始的任务是无法取消的。而GCD是fire and forget模式。
-
指定操作间的依赖关系,指定特定的任务必须在某个任务完成后执行。
-
可以通过KVO监控NSOperation对象的属性。通过KVO就可以在何时结束何时挂起获得通知,进而做一些处理
-
指定操作间的优先级。GCD的优先级是针对整个队列来说的,操作队列就能比较方便的实现优先级操作
-
重用NSOperation对象。
参考
- 《Effective Objective-C 2.0》
- 《Concurrency Programming Guide》
网友评论