NSOperationQueue、NSOperation及其子类介绍

上篇文章写到GCD,GCD的优点是我们只需要定义想要执行的任务并追加到适当的Dispatch Queue中,GCD负责生成线程、计划执行任务并管理线程的生命周期,其线程管理是作为系统的一部分来实现的,因此可统一管理,所以效率很高,而且形式上十分简洁。

GCD看似很完美了,但是GCD是基于C语言开发的,而NSOperation是基于GCD且面向对象的技术,比GCD多了一些简单实用的功能。虽然NSOperation会增加额外的开销,但是更加灵活。NSOperation对应GCD的任务,NSOperationQueue对应GCD的队列。

NSOperation

NSOperation是一个抽象类,我们创建需要执行的任务时,需要使用其子类。Apple为我们定义了两个NSOperation的子类:NSInvocationOperation和NSBlockOperation,另外我们可以自定义NSOperation的子类。

NSOperationQueue

有两种NSOperationQueue:

主队列:通过下面方法获取,放到主队列的任务在主线程执行

NSOperationQueue*queue = [NSOperationQueuemainQueue];

非主队列

NSOperationQueue*queue = [[NSOperationQueuealloc]init];

非主队列既可以并发执行任务也可以串行执行任务,通过设置最大并发数来控制。最大并发数默认为-1,表示不受限制,如果最大并发数为1则是串行队列。非主队列无论是并发队列还是串行队列都不在主线程中执行。

NSOperation可以调用start方法来执行任务,而不用加入到NSOperationQueue中,但是该任务将会在当前线程同步执行。

NSInvocationOperation

NSInvocationOperation *io = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationTest) object:nil];

NSOperationQueue *queue = [[NSOperationQueue alloc] init];

[queue addOperation:io];

- (void)invocationTest {

for(int i =0; i <100; i++) {

NSLog(@"mainThread: %@, currentThread: %@", [NSThreadmainThread], [NSThreadcurrentThread]);

}

}

NSBlockOperation

NSOperationQueue *queue = [[NSOperationQueue alloc] init];

NSBlockOperation *bo = [NSBlockOperation blockOperationWithBlock:^ {

for(int i =0; i <100; i++) {

NSLog(@"%@",[NSThread currentThread]);

}

}];

[queue addOperation:bo];

自定义非并发的NSOperation子类:

我们要自定义初始化方法,并重写- (void)main {};方法,在此方法中需要能相应取消时间。

其余方法:

NSBlockOperation的addExecutionBlock方法:

NSBlockOperation *blockOperation = [NSBlockOperationblock OperationWithBlock:^{

NSLog(@"block1 : currentThread: %@", [NSThread currentThread]);

sleep(3);

}];

[blockOperation addExecutionBlock:^{

NSLog(@"block2 : currentThread: %@", [NSThread currentThread]);

sleep(3);

}];

[blockOperation addExecutionBlock:^{

NSLog(@"block3 : currentThread: %@", [NSThread currentThread]);

sleep(3);

}];

[blockOperation start];

结果:Block1是在主线程中执行的,block2和block3不是。

添加依赖:

[io addDependency:bo];

io会在bo执行完后执行,不同队列的operation之间可以添加依赖。

可通过下面方法执行operation完毕后的操作。

io.completionBlock= ^{

NSLog(@"finish");

};

我们经常需要在非主线程完成后回到主线程刷新UI:

NSBlockOperation *bo = [NSBlockOperation blockOperationWithBlock:^ {

for(inti =0; i <100; i++) {

NSLog(@"%@",[NSThread currentThread]);

}

[[NSOperationQueue mainQueue] addOperationWithBlock:^{

NSLog(@"=====%@",[NSThreadcurrentThread]);

}];;

}];

暂停任务:

queue.suspended = YES;

恢复任务:

queue.suspended=NO;

取消所有任务,一旦取消不可逆

[queue cancelAllOperations];

暂停和取消只能暂停或取消处于等待状态的任务,不能暂停或取消正在执行中的任务


你可能感兴趣的:(NSOperationQueue、NSOperation及其子类介绍)