概述
NSOperation
是对``GCD的封装,完全
面向对象,使用起来更好理解。
NSOperation对应
GCD中的
任务(操作),有
同步任务和
异步任务之分。
NSOperationQueue对应
GCD中的
队列,有
串行队列和
并行队列`之分。
任务
NSOperation
是一个抽象类,在使用的时候需要用到它的3个子类
1 NSInvocationOperation
- (void)OPERATION01
{
//doSomething在主线程中执行
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSomething) object:nil];
[op start];
}
2 NSBlockOperation
- (void)OPERATION02
{
//打印语句在主线程中执行
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"OPERATION02 %@", [NSThread currentThread]);
}];
[op start];
}
- (void)OPERATION03
{
//所有的打印语句是并发执行的,也就是在主线程和子线程中执行
//
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"OPERATION03 %@", [NSThread currentThread]);
}];
for (NSInteger i = 0; i < 10; i++) {
[op addExecutionBlock:^{
NSLog(@"OPERATION03 -- %ld -- %@", (long)i, [NSThread currentThread]);
}];
}
[op start];
}
3 自定义NSOperation
队列
通过上面的代码可知,可以调用NSOperation
的start
方法来启动任务,这样做默认是同步执行
的,就算使用了addExecutionBlock
方法,也会在当前线程
和其他线程中
执行,当前线程
还是会被占用。这时候,就需要NSOperationQueue
发挥作用了
1 主队列
NSOperationQueue *queue = [NSOperationQueue mainQueue];
主队列里的任务在主线程里一个接一个地排队执行,等同于GCD
中的dispatch_get_main_queue()
2 其他队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
其他队列里的任务在子线程并行执行,
等同于GCD中的dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT)
如果设置queue.maxConcurrentOperationCount = 1
则等同于GCD中的dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL)
3 示例
- (void)OPERATION04
{
// NSOperationQueue *queue = [NSOperationQueue mainQueue];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 1;
for (NSInteger i = 0; i < 10; i++) {
[queue addOperationWithBlock:^{
[NSThread sleepForTimeInterval:1];
NSLog(@"OPERATION04 -- %ld -- %@", (long)i, [NSThread currentThread]);
}];
}
}
4 组以及依赖
队列的addOperations: waitUntilFinished:
方法和GCD
中dispatch_group
的功能相似,提供了组的概念
- (void)OPERATION05
{
NSLog(@"开始 %@", [NSThread currentThread]);
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
[NSThread sleepForTimeInterval:5];
NSLog(@"步骤1 %@", [NSThread currentThread]);
}];
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
[NSThread sleepForTimeInterval:3];
NSLog(@"步骤2 %@", [NSThread currentThread]);
}];
NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
[NSThread sleepForTimeInterval:1];
NSLog(@"步骤3 %@", [NSThread currentThread]);
}];
/*
可添加任务之间的依赖关系,执行的先后顺序
1 相互依赖会造成死锁
2 可以使用 removeDependency] 来解除依赖关系
3 可以在不同的队列之间依赖,反正就是这个依赖是添加到任务身上的,和队列没关系。
*/
[op2 addDependency:op1];
[op3 addDependency:op2];
NSOperationQueue *queue = [NSOperationQueue new];
/*
If YES, the current thread is blocked until all of the specified operations finish executing.
If NO, the operations are added to the queue and control returns immediately to the caller.
如果为YES,阻塞当前线程直到数组里面的操作全部完成
如果为NO,在把任务添加到数组后立即返回执行后面的代码
*/
[queue addOperations:@[op1, op2, op3] waitUntilFinished:YES];
[queue addOperationWithBlock:^{
NSLog(@"完成 %@", [NSThread currentThread]);
}];
}
5 NSOperationQueue其他方法
- (void)cancelAllOperations; //取消队列中所有的任务
- (void)waitUntilAllOperationsAreFinished; //阻塞当前线程直到此队列中的所有任务执行完毕
[queue setSuspended:YES]; // 暂停queue
[queue setSuspended:NO]; // 继续queue