文章目录
  1. 1. 介绍
  2. 2. NSOperation相比GCD的优势
  3. 3. 1.使用
    1. 3.1. 1.NSInvocationOperation基础例子(mainQueue是串行的.)
    2. 3.2. 2.NSBlockOperation基础例子
  4. 4. 2.进阶
    1. 4.1. 1.mainQueue是串行的.
    2. 4.2. 2.自定义NSOperationQueue
    3. 4.3. 3.添加依赖
    4. 4.4. 4.设置最大并行数

介绍

NSOperation是苹果对GCD的一个抽象封装。GCD 是基于 C 的底层的 API ,而 NSOperation 则是 GCD 实现的 Objective-C API。 虽然 NSOperation 是基于 GCD 实现的, 但是并不意味着它是一个 GCD 的 “dumbed-down” 版本, 相反,我们可以用NSOperation 轻易的实现一些 GCD 要写大量代码的事情。可以实现GCD不能实现的中断线程,合并等操作。

NSOperation相比GCD的优势

  • 提供了在 GCD 中不那么容易复制的有用特性。
  • 可以很方便的取消一个NSOperation的执行
  • 可以更容易的添加任务的依赖关系
  • 提供了任务的状态:isReady → isExecuting → isFinished 对应 准备 → 执行 → 完成

1.使用

  1. 建立一个NSOperationQueue的对象

  2. 建立一个NSOperation的对象

  3. 将operation加入到NSOperationQueue中
    跟GCD一模一样,谁让抽象自GCD

IOS提供了两个常用的,NSInvocationOperation,NSInvocationOperation是NSOperation的子类,允许运行在operation中的targer和selector。

1.NSInvocationOperation基础例子(mainQueue是串行的.)

- (void)viewDidLoad {
    [super viewDidLoad];
    NSOperationQueue *queue = [NSOperationQueue mainQueue];
    NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download:) object:@"hello"];
    [queue addOperation:operation];
    NSLog(@"i'm back");
}

-(void)download:(id)data{
    sleep(5);
    NSLog(@"dat:%@, thread:%@",data,[NSThread currentThread]);
}

看下方输出可以看出先执行了“i’m back”, 五秒后执行download方法里的打印。并没有阻塞主线程。
`2015-08-26 17:35:32.536 test[26697:5430809] i’m back
2015-08-26 17:35:37.585 test[26697:5430809] thread:\{number = 1, name = main}`

2.NSBlockOperation基础例子

- (void)viewDidLoad {
    [super viewDidLoad];
    NSOperationQueue *queue = [NSOperationQueue mainQueue];

    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
        sleep(5);
        NSLog(@"thread:%@",[NSThread currentThread]);
    }];
    [queue addOperation:blockOperation];
    NSLog(@"i'm back");
}

输出结果是一样的:
`2015-08-26 17:37:30.827 test[26721:5446451] i’m back
2015-08-26 17:37:35.875 test[26721:5446451] thread:\{number = 1, name = main}`

2.进阶

1.mainQueue是串行的.

- (void)viewDidLoad {
    [super viewDidLoad];
    NSOperationQueue *queue = [NSOperationQueue mainQueue];
//    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    NSInvocationOperation *operation1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download:) object:nil];
    NSInvocationOperation *operation2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download:) object:nil];
    NSInvocationOperation *operation3 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download:) object:nil];
    [queue addOperation:operation1];
    [queue addOperation:operation2];
    [queue addOperation:operation3];
    NSLog(@"i'm back");
}

-(void)download:(id)data{
    sleep(2);
    NSLog(@"dat:%@, thread:%@",data,[NSThread currentThread]);
}

打印结果:串行执行,两秒两秒
2015-08-26 17:45:14.381 test[26889:5494493] i’m back
2015-08-26 17:45:16.411 test[26889:5494493] dat:(null), thread:{number = 1, name = main}
2015-08-26 17:45:18.419 test[26889:5494493] dat:(null), thread:{number = 1, name = main}
2015-08-26 17:45:20.428 test[26889:5494493] dat:(null), thread:{number = 1, name = main}

2.自定义NSOperationQueue

- (void)viewDidLoad {
    [super viewDidLoad];
//    NSOperationQueue *queue = [NSOperationQueue mainQueue];
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    NSInvocationOperation *operation1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download:) object:nil];
    NSInvocationOperation *operation2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download:) object:nil];
    NSInvocationOperation *operation3 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download:) object:nil];
    [queue addOperation:operation1];
    [queue addOperation:operation2];
    [queue addOperation:operation3];
    NSLog(@"i'm back");
}

-(void)download:(id)data{
    sleep(2);
    NSLog(@"dat:%@, thread:%@",data,[NSThread currentThread]);
}

打印结果:并行执行,都是2秒后统一打印
2015-08-26 17:46:56.371 test[26927:5507100] i’m back
2015-08-26 17:46:58.373 test[26927:5507197] dat:(null), thread:{number = 2, name = (null)}
2015-08-26 17:46:58.373 test[26927:5507200] dat:(null), thread:{number = 4, name = (null)}
2015-08-26 17:46:58.373 test[26927:5507198] dat:(null), thread:{number = 3, name = (null)}

3.添加依赖

- (void)viewDidLoad {
    [super viewDidLoad];
//    NSOperationQueue *queue = [NSOperationQueue mainQueue];
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    NSInvocationOperation *operation1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download:) object:@"i'm 1"];
    NSInvocationOperation *operation2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download:) object:@"i'm 2"];
    NSInvocationOperation *operation3 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download:) object:@"i'm 3"];
    [operation3 addDependency:operation1];  //依赖

    [queue addOperation:operation1];
    [queue addOperation:operation2];
    [queue addOperation:operation3];
    NSLog(@"i'm back");
}

-(void)download:(id)data{
    sleep(2);
    NSLog(@"dat:%@, thread:%@",data,[NSThread currentThread]);
}

打印结果:operation3 在 operation1执行完成后才能执行
2015-08-26 17:49:15.123 test[26986:5516833] i’m back
2015-08-26 17:49:17.124 test[26986:5516907] dat:i’m 2, thread:{number = 3, name = (null)}
2015-08-26 17:49:17.124 test[26986:5516908] dat:i’m 1, thread:{number = 2, name = (null)}
2015-08-26 17:49:19.129 test[26986:5516907] dat:i’m 3, thread:{number = 3, name = (null)}

4.设置最大并行数

[queue setMaxConcurrentOperationCount:5];

  - (void)viewDidLoad {
    [super viewDidLoad];
//    NSOperationQueue *queue = [NSOperationQueue mainQueue];
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    [queue setMaxConcurrentOperationCount:5];
    NSInvocationOperation *operation1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download:) object:@"i'm 1"];
    NSInvocationOperation *operation2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download:) object:@"i'm 2"];
    NSInvocationOperation *operation3 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download:) object:@"i'm 3"];
    NSInvocationOperation *operation4 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download:) object:@"i'm 4"];
    NSInvocationOperation *operation5 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download:) object:@"i'm 5"];
    NSInvocationOperation *operation6 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download:) object:@"i'm 6"];

    [queue addOperation:operation1];
    [queue addOperation:operation2];
    [queue addOperation:operation3];
    [queue addOperation:operation4];
    [queue addOperation:operation5];
    [queue addOperation:operation6];
}

-(void)download:(id)data{
    sleep(1);
    NSLog(@"dat:%@, thread:%@",data,[NSThread currentThread]);
}

打印结果:operation6在其他完成了才能执行。因为限制了最大并发数为5
2015-08-26 17:54:07.075 test[27065:5546263] dat:i’m 2, thread:{number = 6, name = (null)}
2015-08-26 17:54:07.075 test[27065:5546265] dat:i’m 1, thread:{number = 4, name = (null)}
2015-08-26 17:54:07.076 test[27065:5546292] dat:i’m 4, thread:{number = 3, name = (null)}
2015-08-26 17:54:07.076 test[27065:5546293] dat:i’m 5, thread:{number = 5, name = (null)}
2015-08-26 17:54:07.075 test[27065:5546291] dat:i’m 3, thread:{number = 2, name = (null)}
2015-08-26 17:54:08.081 test[27065:5546265] dat:i’m 6, thread:{number = 4, name = (null)}

文章目录
  1. 1. 介绍
  2. 2. NSOperation相比GCD的优势
  3. 3. 1.使用
    1. 3.1. 1.NSInvocationOperation基础例子(mainQueue是串行的.)
    2. 3.2. 2.NSBlockOperation基础例子
  4. 4. 2.进阶
    1. 4.1. 1.mainQueue是串行的.
    2. 4.2. 2.自定义NSOperationQueue
    3. 4.3. 3.添加依赖
    4. 4.4. 4.设置最大并行数