1.NSOperation的理解
NSOperation本身是一个抽象的基类,我们要自己子类化NSOpeartion并封装我们要完成的任务,系统提供了两个比较方便的子类 NSInvocationOperation 和 NSBlockOperation ,NSInvocationOperation方便我们以现有的方法来初始化一个operation,NSBlockOperation是方便我们从Block来初始化operation。所有的NSOperation都有如下特征:- 支持NSOperation对象之间建立依赖关系,当一个operation的所有依赖的operation都执行完了自己才会执行。
- 支持可选的completion block,当operation的主任务完成之后调用。
- 支持通过KVO通知来监控operation的执行状态。
- 支持指定operaion的优先级来安排operation的相对指向顺序。
- 支持operation的取消操作来停止operation执行。
2.NSOperation的执行
通常情况下我们要并发执行的话只要简单的把operation添加到operation queue中就行,operation queue负责创建线程并发地执行operation任务。- MyOperation *operation = [MyOperation alloc] init];
- NSOperationQueue* aQueue = [[NSOperationQueue alloc] init];
- [aQueue addOperation:operation];
- MyOperation *operation = [MyOperation alloc] init];
- [operation start];
3.NSInvocationOperation的使用
- @implementation MyCustomClass
- - (NSOperation*)taskWithData:(id)data
- {
- NSInvocationOperation* theOp = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(myTaskMethod:) object:data];
- return theOp;
- }
- // This is the method that does the actual work of the task.
- - (void)myTaskMethod:(id)data
- {
- // Perform the task.
- }
- @end
4.NSBlockOperation的使用
- NSBlockOperation* theOp = [NSBlockOperation blockOperationWithBlock: ^
- {
- NSLog(@"Beginning operation.\n");
- // Do some work.
- }];
5.自定义NSOperation
NSOperation提供了一个基本结构,具体相关的并发执行的方法、operation依赖、KVO通知和取消操作还是需要我们自己实现的。整个NSOperation子类实现如下:- @interface MyOperation : NSOperation {
- BOOL executing;
- BOOL finished;
- }
- - (void)completeOperation;
- @end
- @implementation MyOperation
- - (id)init {
- self = [super init];
- if (self) {
- executing = NO;
- finished = NO;
- }
- return self;
- }
- - (void)start {
- // Always check for cancellation before launching the task.
- if ([self isCancelled])
- {
- // Must move the operation to the finished state if it is canceled.
- [self willChangeValueForKey:@"isFinished"];
- finished = YES;
- [self didChangeValueForKey:@"isFinished"];
- return;
- }
- // If the operation is not canceled, begin executing the task.
- [self willChangeValueForKey:@"isExecuting"];
- [self main];
- executing = YES;
- [self didChangeValueForKey:@"isExecuting"];
- }
- - (void)main {
- @autoreleasepool {
- BOOL isDone = NO;
- while (![self isCancelled] && !isDone) {
- // Do some work and set isDone to YES when finished
- }
- [self completeOperation];
- }
- }
- - (void)completeOperation {
- [self willChangeValueForKey:@"isFinished"];
- [self willChangeValueForKey:@"isExecuting"];
- executing = NO;
- finished = YES;
- [self didChangeValueForKey:@"isExecuting"];
- [self didChangeValueForKey:@"isFinished"];
- }
- - (void)cancel {
- [super cancel];
- //取消网络请求
- }
- - (BOOL)isConcurrent {
- return YES;
- }
- - (BOOL)isExecuting {
- return executing;
- }
- - (BOOL)isFinished {
- return finished;
- }
- @end
- start
- main
- isConcurrent
- isExecuting
- isFinished
- isCancelled
- isConcurrent
- isExecuting
- isFinished
- isReady
- dependencies
- queuePriority
- completionBlock
6.配置NSOperation
6.1依赖管理
我们可以通过addDependency:给当前operation添加依赖operation,依赖关系不限于operation是否在一个队列里。注意我们不要自己生成循环依赖,这样会造成死锁。6.2优先级管理
在队列里的operation的执行顺序取决于operation的状态(是否准备就绪)和相对优先级。是否准备就绪取决于operation的依赖operation是否完成,执行队列会优先考虑operation,如果高优先级的operation没有准备就绪,执行队列就会先执行低优先级的operation。operation的相对优先级只针对同一队列,就是说一个低优先级的operation可能比另一个队列里高优先级的operation优先执行。6.3底层线程优先级管理
我们可以通过setThreadPriority:设置operation系统级别的线程优先级,优先级由0.0到1.0浮点数指定,默认是0.5。我们自己设置的系统级别的线程优先级只针对main方法执行期间有效,其他方法都是按照默认优先级执行。