NSOperation一些总结

1-NSInvocationOperation

2-NSBlockOperation

3-NSOperationQueue管理任务

4-NSOperation任务间依赖

5-线程间通信(最重要的代码)


1-NSInvocationOperation

1.[NSInvocationOperation alloc] initWithTarget:self selector:@selector() object:
2.[q addOperation:op]

// MARK: 单个NSInvocationOperation使用
- (void)opDemo1
{
    // 1. 创建操作
    NSOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadImage:) object:@"Invocation"];

    // 2. 启动-- 直接在当前线程执行任务
//    [op start];

//    [self downloadImage:@""];

    // 2. 放到队列
    NSOperationQueue *q = [[NSOperationQueue alloc] init];
    // 只要把操作添加到队列, ---会自动异步执行调度方法
    [q addOperation:op];

    /*添加的任务在新的线程中执行
     2016-03-21 18:25:52.886 01-NSOperation演练(掌握)[3267:2596675] <NSThread: 0x7f9e11e16720>{number = 2, name = (null)}---Invocation
     */
}

#pragma mark - 耗时操作
- (void)downloadImage:(id)obj
{
    NSLog(@"%@---%@", [NSThread currentThread], obj);
}

// MARK: 多个NSInvocationOperation使用
- (void)opDemo2
{
    // 队列 (GCD里面的并发(全局)队列使用最多。所以NSOperation技术直接把GCD里面的并发队列封装起来)
    // NSOperationQueue队列,本质就是GCD里面的并发队列
    // 操作就是GCD里面异步执行的任务
    NSOperationQueue *q = [[NSOperationQueue alloc] init];

    // 把多个操作放到队列
    for (int i = 0 ; i < 10; i++)
    {
        NSOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadImage:) object:@"Invocation"];

        // 把block操作放到队列
        [q addOperation:op];
         NSLog(@"---A---");
    }
    NSLog(@"---B---");
    /*op被添加到q之后就会执行,各个任务之间是并发执行没有顺序可言
     2016-03-21 18:34:51.471 01-NSOperation演练(掌握)[3298:2633681] ---A---
     2016-03-21 18:34:51.471 01-NSOperation演练(掌握)[3298:2634074] <NSThread: 0x7f94c340ef90>{number = 2, name = (null)}---Invocation
     2016-03-21 18:34:51.471 01-NSOperation演练(掌握)[3298:2633681] ---A---
     2016-03-21 18:34:51.472 01-NSOperation演练(掌握)[3298:2633681] ---A---
     2016-03-21 18:34:51.472 01-NSOperation演练(掌握)[3298:2633681] ---A---
     2016-03-21 18:34:51.472 01-NSOperation演练(掌握)[3298:2633681] ---A---
     2016-03-21 18:34:51.472 01-NSOperation演练(掌握)[3298:2633681] ---A---
     2016-03-21 18:34:51.473 01-NSOperation演练(掌握)[3298:2633681] ---A---
     2016-03-21 18:34:51.472 01-NSOperation演练(掌握)[3298:2634067] <NSThread: 0x7f94c34304d0>{number = 3, name = (null)}---Invocation
     2016-03-21 18:34:51.473 01-NSOperation演练(掌握)[3298:2633681] ---A---
     2016-03-21 18:34:51.472 01-NSOperation演练(掌握)[3298:2634070] <NSThread: 0x7f94c36229c0>{number = 4, name = (null)}---Invocation
     2016-03-21 18:34:51.473 01-NSOperation演练(掌握)[3298:2633681] ---A---
     2016-03-21 18:34:51.473 01-NSOperation演练(掌握)[3298:2634074] <NSThread: 0x7f94c340ef90>{number = 2, name = (null)}---Invocation
     2016-03-21 18:34:51.473 01-NSOperation演练(掌握)[3298:2633681] ---A---
     2016-03-21 18:34:51.474 01-NSOperation演练(掌握)[3298:2633681] ---B---
     2016-03-21 18:34:51.474 01-NSOperation演练(掌握)[3298:2634074] <NSThread: 0x7f94c340ef90>{number = 2, name = (null)}---Invocation
     2016-03-21 18:34:51.474 01-NSOperation演练(掌握)[3298:2634070] <NSThread: 0x7f94c36229c0>{number = 4, name = (null)}---Invocation
     2016-03-21 18:34:51.473 01-NSOperation演练(掌握)[3298:2634326] <NSThread: 0x7f94c3757fa0>{number = 5, name = (null)}---Invocation
     2016-03-21 18:34:51.475 01-NSOperation演练(掌握)[3298:2634067] <NSThread: 0x7f94c34304d0>{number = 3, name = (null)}---Invocation
     2016-03-21 18:34:51.475 01-NSOperation演练(掌握)[3298:2634074] <NSThread: 0x7f94c340ef90>{number = 2, name = (null)}---Invocation
     2016-03-21 18:34:51.475 01-NSOperation演练(掌握)[3298:2634070] <NSThread: 0x7f94c36229c0>{number = 4, name = (null)}---Invocation
     */

}

2-NSBlockOperation

// MARK: NSBlockOperation更简单的使用
- (void)opDemo4
{
    // 队列
    NSOperationQueue *q = [[NSOperationQueue alloc] init];

    for (int i = 0; i < 10; i++) {
        // 不创建操作对象,使用addOperationWithBlock:直接添加操作到队列
        [q addOperationWithBlock:^{
            NSLog(@"%@---%d", [NSThread currentThread], i);
        }];
    }

    // 创建并添加一个 NSBlockOperation
    NSBlockOperation * op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"op1 --- %@", [NSThread currentThread]);

    }];

    [op1 addExecutionBlock:^{
        NSLog(@"op1-1");
    }];

    [q addOperation:op1];

    // 创建并添加一个 NSInvocationOperation
    NSOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadImage:) object:@"Invocation"];
    [q addOperation:op2];

    /*
     2016-03-21 18:50:50.837 01-NSOperation演练(掌握)[3326:2738328] <NSThread: 0x7ff37273db20>{number = 22, name = (null)}---0
     2016-03-21 18:50:50.837 01-NSOperation演练(掌握)[3326:2738325] <NSThread: 0x7ff37262f7e0>{number = 23, name = (null)}---1
     2016-03-21 18:50:50.838 01-NSOperation演练(掌握)[3326:2738336] <NSThread: 0x7ff3727516e0>{number = 24, name = (null)}---2
     2016-03-21 18:50:50.838 01-NSOperation演练(掌握)[3326:2738328] <NSThread: 0x7ff37273db20>{number = 22, name = (null)}---3
     2016-03-21 18:50:50.839 01-NSOperation演练(掌握)[3326:2738338] <NSThread: 0x7ff372759d20>{number = 25, name = (null)}---4
     2016-03-21 18:50:50.839 01-NSOperation演练(掌握)[3326:2738325] <NSThread: 0x7ff37262f7e0>{number = 23, name = (null)}---5
     2016-03-21 18:50:50.839 01-NSOperation演练(掌握)[3326:2738336] <NSThread: 0x7ff3727516e0>{number = 24, name = (null)}---6
     2016-03-21 18:50:50.839 01-NSOperation演练(掌握)[3326:2738342] <NSThread: 0x7ff37273e370>{number = 26, name = (null)}---7
     2016-03-21 18:50:50.840 01-NSOperation演练(掌握)[3326:2738328] <NSThread: 0x7ff37273db20>{number = 22, name = (null)}---8
     2016-03-21 18:50:50.840 01-NSOperation演练(掌握)[3326:2738343] <NSThread: 0x7ff3727550d0>{number = 27, name = (null)}---9
     2016-03-21 18:50:50.841 01-NSOperation演练(掌握)[3326:2738330] op1 --- <NSThread: 0x7ff372733d10>{number = 28, name = (null)}
     2016-03-21 18:50:50.841 01-NSOperation演练(掌握)[3326:2738336] op1-1
     2016-03-21 18:50:50.843 01-NSOperation演练(掌握)[3326:2738327] <NSThread: 0x7ff372408d50>{number = 29, name = (null)}---Invocation

    */

}

// MARK: NSBlockOperation使用
- (void)opDemo3
{
    // 相当于GCD的并发队列
    NSOperationQueue *q = [[NSOperationQueue alloc] init];

    // 主队列(跟GCD里的主队列一样)
//    NSOperationQueue *q = [NSOperationQueue mainQueue];

    // 多个操作
    for (int i = 0; i < 10; i++) {
        NSBlockOperation * op = [NSBlockOperation blockOperationWithBlock:^{
            NSLog(@"%@---%d", [NSThread currentThread], i);
        }];

        // 把block操作放到队列
        [q addOperation:op];
    }

    NSLog(@"完成");
    /*个任务之间是并发执行
     2016-03-21 18:43:19.814 01-NSOperation演练(掌握)[3312:2685152] <NSThread: 0x7fb9eb7187f0>{number = 35, name = (null)}---0
     2016-03-21 18:43:19.814 01-NSOperation演练(掌握)[3312:2666918] 完成
     2016-03-21 18:43:19.814 01-NSOperation演练(掌握)[3312:2686480] <NSThread: 0x7fb9eb63d090>{number = 38, name = (null)}---1
     2016-03-21 18:43:19.814 01-NSOperation演练(掌握)[3312:2685151] <NSThread: 0x7fb9eb74a420>{number = 34, name = (null)}---3
     2016-03-21 18:43:19.814 01-NSOperation演练(掌握)[3312:2685153] <NSThread: 0x7fb9eb747350>{number = 36, name = (null)}---2
     2016-03-21 18:43:19.815 01-NSOperation演练(掌握)[3312:2685152] <NSThread: 0x7fb9eb7187f0>{number = 35, name = (null)}---4
     2016-03-21 18:43:19.815 01-NSOperation演练(掌握)[3312:2685563] <NSThread: 0x7fb9eb7393a0>{number = 37, name = (null)}---5
     2016-03-21 18:43:19.815 01-NSOperation演练(掌握)[3312:2686480] <NSThread: 0x7fb9eb63d090>{number = 38, name = (null)}---6
     2016-03-21 18:43:19.815 01-NSOperation演练(掌握)[3312:2685151] <NSThread: 0x7fb9eb74a420>{number = 34, name = (null)}---7
     2016-03-21 18:43:19.816 01-NSOperation演练(掌握)[3312:2685152] <NSThread: 0x7fb9eb7187f0>{number = 35, name = (null)}---9
     2016-03-21 18:43:19.816 01-NSOperation演练(掌握)[3312:2685153] <NSThread: 0x7fb9eb747350>{number = 36, name = (null)}---8

     2016-03-21 18:43:20.005 01-NSOperation演练(掌握)[3312:2666918] 完成
     2016-03-21 18:43:20.005 01-NSOperation演练(掌握)[3312:2685151] <NSThread: 0x7fb9eb74a420>{number = 34, name = (null)}---2
     2016-03-21 18:43:20.006 01-NSOperation演练(掌握)[3312:2685152] <NSThread: 0x7fb9eb7187f0>{number = 35, name = (null)}---1
     2016-03-21 18:43:20.006 01-NSOperation演练(掌握)[3312:2686480] <NSThread: 0x7fb9eb63d090>{number = 38, name = (null)}---3
     2016-03-21 18:43:20.006 01-NSOperation演练(掌握)[3312:2685153] <NSThread: 0x7fb9eb747350>{number = 36, name = (null)}---0
     2016-03-21 18:43:20.006 01-NSOperation演练(掌握)[3312:2685151] <NSThread: 0x7fb9eb74a420>{number = 34, name = (null)}---4
     2016-03-21 18:43:20.006 01-NSOperation演练(掌握)[3312:2685152] <NSThread: 0x7fb9eb7187f0>{number = 35, name = (null)}---6
     2016-03-21 18:43:20.007 01-NSOperation演练(掌握)[3312:2685563] <NSThread: 0x7fb9eb7393a0>{number = 37, name = (null)}---5
     2016-03-21 18:43:20.007 01-NSOperation演练(掌握)[3312:2686480] <NSThread: 0x7fb9eb63d090>{number = 38, name = (null)}---7
     2016-03-21 18:43:20.007 01-NSOperation演练(掌握)[3312:2685153] <NSThread: 0x7fb9eb747350>{number = 36, name = (null)}---8
     2016-03-21 18:43:20.007 01-NSOperation演练(掌握)[3312:2685143] <NSThread: 0x7fb9eb60e270>{number = 31, name = (null)}---9
     */

}

3-NSOperationQueue管理任务

测试API:
1.[self.opQueue cancelAllOperations]; 取消队列任务
2.suspended  队列暂停
3.self.opQueue.maxConcurrentOperationCount = 2; 队列最大并发数

// MARK: 暂停/继续 (对队列的暂停和继续)
- (IBAction)pause
{
    // 判断操作的数量,当前队列里面是不是有操作
    if (self.opQueue.operationCount == 0) {
        NSLog(@"没有操作");
        return;
    }

    // 暂停/继续
//    @property(nonatomic,strong) NSOperationQueue *opQueue;
    self.opQueue.suspended = !self.opQueue.suspended;

    if (self.opQueue.suspended) { // 队列的挂起以后,队列里面的操作还在
        NSLog(@"暂停");
    }else{
        NSLog(@"继续");
    }
    /*
     2016-03-22 00:31:36.957 01-NSOperation演练(掌握)[20682:3476480] <NSThread: 0x7fb1d3509f30>{number = 2, name = (null)}---1
     2016-03-22 00:31:36.957 01-NSOperation演练(掌握)[20682:3476483] <NSThread: 0x7fb1d58803e0>{number = 3, name = (null)}---0
     2016-03-22 00:31:39.033 01-NSOperation演练(掌握)[20682:3476492] <NSThread: 0x7fb1d584e270>{number = 4, name = (null)}---2
     2016-03-22 00:31:39.033 01-NSOperation演练(掌握)[20682:3476491] <NSThread: 0x7fb1d58898d0>{number = 5, name = (null)}---3
     2016-03-22 00:31:39.647 01-NSOperation演练(掌握)[20682:3476355] 暂停
     2016-03-22 00:31:41.107 01-NSOperation演练(掌握)[20682:3476492] <NSThread: 0x7fb1d584e270>{number = 4, name = (null)}---5
     2016-03-22 00:31:41.107 01-NSOperation演练(掌握)[20682:3476483] <NSThread: 0x7fb1d58803e0>{number = 3, name = (null)}---4
     2016-03-22 00:31:47.771 01-NSOperation演练(掌握)[20682:3476355] 继续
     2016-03-22 00:31:49.845 01-NSOperation演练(掌握)[20682:3476492] <NSThread: 0x7fb1d584e270>{number = 4, name = (null)}---7
     2016-03-22 00:31:49.845 01-NSOperation演练(掌握)[20682:3476483] <NSThread: 0x7fb1d58803e0>{number = 3, name = (null)}---6
     2016-03-22 00:31:51.918 01-NSOperation演练(掌握)[20682:3476492] <NSThread: 0x7fb1d584e270>{number = 4, name = (null)}---9
     2016-03-22 00:31:51.918 01-NSOperation演练(掌握)[20682:3476491] <NSThread: 0x7fb1d58898d0>{number = 5, name = (null)}---8
     2016-03-22 00:31:53.991 01-NSOperation演练(掌握)[20682:3476483] <NSThread: 0x7fb1d58803e0>{number = 3, name = (null)}---10
     2016-03-22 00:31:53.991 01-NSOperation演练(掌握)[20682:3476492] <NSThread: 0x7fb1d584e270>{number = 4, name = (null)}---11
     2016-03-22 00:31:54.851 01-NSOperation演练(掌握)[20682:3476355] 暂停
     2016-03-22 00:31:56.066 01-NSOperation演练(掌握)[20682:3476491] <NSThread: 0x7fb1d58898d0>{number = 5, name = (null)}---12
     2016-03-22 00:31:56.066 01-NSOperation演练(掌握)[20682:3476483] <NSThread: 0x7fb1d58803e0>{number = 3, name = (null)}---13
     2016-03-22 00:31:59.163 01-NSOperation演练(掌握)[20682:3476355] 继续
     2016-03-22 00:32:01.234 01-NSOperation演练(掌握)[20682:3476491] <NSThread: 0x7fb1d58898d0>{number = 5, name = (null)}---15
     2016-03-22 00:32:01.234 01-NSOperation演练(掌握)[20682:3476483] <NSThread: 0x7fb1d58803e0>{number = 3, name = (null)}---14
     2016-03-22 00:32:03.306 01-NSOperation演练(掌握)[20682:3476483] <NSThread: 0x7fb1d58803e0>{number = 3, name = (null)}---17
     2016-03-22 00:32:03.306 01-NSOperation演练(掌握)[20682:3476711] <NSThread: 0x7fb1d3521620>{number = 6, name = (null)}---16
     2016-03-22 00:32:05.382 01-NSOperation演练(掌握)[20682:3476483] <NSThread: 0x7fb1d58803e0>{number = 3, name = (null)}---18
     2016-03-22 00:32:05.382 01-NSOperation演练(掌握)[20682:3476491] <NSThread: 0x7fb1d58898d0>{number = 5, name = (null)}---19
     2016-03-22 00:32:07.456 01-NSOperation演练(掌握)[20682:3476491] <NSThread: 0x7fb1d58898d0>{number = 5, name = (null)}---0
     2016-03-22 00:32:07.456 01-NSOperation演练(掌握)[20682:3476711] <NSThread: 0x7fb1d3521620>{number = 6, name = (null)}---1
     2016-03-22 00:32:09.531 01-NSOperation演练(掌握)[20682:3476711] <NSThread: 0x7fb1d3521620>{number = 6, name = (null)}---3
     2016-03-22 00:32:09.531 01-NSOperation演练(掌握)[20682:3476483] <NSThread: 0x7fb1d58803e0>{number = 3, name = (null)}---2
     2016-03-22 00:32:11.606 01-NSOperation演练(掌握)[20682:3476711] <NSThread: 0x7fb1d3521620>{number = 6, name = (null)}---4
     2016-03-22 00:32:11.606 01-NSOperation演练(掌握)[20682:3476483] <NSThread: 0x7fb1d58803e0>{number = 3, name = (null)}---5
     2016-03-22 00:32:13.681 01-NSOperation演练(掌握)[20682:3476789] <NSThread: 0x7fb1d3417940>{number = 7, name = (null)}---6
     2016-03-22 00:32:13.681 01-NSOperation演练(掌握)[20682:3476711] <NSThread: 0x7fb1d3521620>{number = 6, name = (null)}---7
     */

}

// MARK: 最大并发数
- (void)opDemo6
{
    // 设置最大的并发数是2 (最大并发数,不是线程的数量。 而是同时执行的操作的数量)
// @property(nonatomic,strong) NSOperationQueue *opQueue;
    self.opQueue.maxConcurrentOperationCount = 2;

    for (int i = 0; i < 20; i++) {
        NSOperation *op = [NSBlockOperation blockOperationWithBlock:^{

            [NSThread sleepForTimeInterval:2.0];

            NSLog(@"%@---%d", [NSThread currentThread], i);
        }];

        [self.opQueue addOperation:op];
    }
    /*
     2016-03-21 23:29:55.438 01-NSOperation演练(掌握)[17248:3441502] <NSThread: 0x7fed48573e00>{number = 7, name = (null)}---0
     2016-03-21 23:29:55.438 01-NSOperation演练(掌握)[17248:3441501] <NSThread: 0x7fed48715960>{number = 6, name = (null)}---1
     2016-03-21 23:29:56.512 01-NSOperation演练(掌握)[17248:3441501] <NSThread: 0x7fed48715960>{number = 6, name = (null)}---3
     2016-03-21 23:29:56.512 01-NSOperation演练(掌握)[17248:3441502] <NSThread: 0x7fed48573e00>{number = 7, name = (null)}---2
     2016-03-21 23:29:57.586 01-NSOperation演练(掌握)[17248:3441501] <NSThread: 0x7fed48715960>{number = 6, name = (null)}---5
     2016-03-21 23:29:57.586 01-NSOperation演练(掌握)[17248:3441849] <NSThread: 0x7fed48426030>{number = 10, name = (null)}---4
     2016-03-21 23:29:58.660 01-NSOperation演练(掌握)[17248:3441501] <NSThread: 0x7fed48715960>{number = 6, name = (null)}---7
     2016-03-21 23:29:58.660 01-NSOperation演练(掌握)[17248:3441502] <NSThread: 0x7fed48573e00>{number = 7, name = (null)}---6
     2016-03-21 23:29:59.735 01-NSOperation演练(掌握)[17248:3441501] <NSThread: 0x7fed48715960>{number = 6, name = (null)}---9
     2016-03-21 23:29:59.735 01-NSOperation演练(掌握)[17248:3441849] <NSThread: 0x7fed48426030>{number = 10, name = (null)}---8
     2016-03-21 23:30:00.810 01-NSOperation演练(掌握)[17248:3441863] <NSThread: 0x7fed48701040>{number = 11, name = (null)}---10
     2016-03-21 23:30:00.810 01-NSOperation演练(掌握)[17248:3441501] <NSThread: 0x7fed48715960>{number = 6, name = (null)}---11
     2016-03-21 23:30:01.884 01-NSOperation演练(掌握)[17248:3441863] <NSThread: 0x7fed48701040>{number = 11, name = (null)}---12
     2016-03-21 23:30:01.884 01-NSOperation演练(掌握)[17248:3441849] <NSThread: 0x7fed48426030>{number = 10, name = (null)}---13
     2016-03-21 23:30:02.958 01-NSOperation演练(掌握)[17248:3441863] <NSThread: 0x7fed48701040>{number = 11, name = (null)}---15
     2016-03-21 23:30:02.958 01-NSOperation演练(掌握)[17248:3441501] <NSThread: 0x7fed48715960>{number = 6, name = (null)}---14
     2016-03-21 23:30:04.034 01-NSOperation演练(掌握)[17248:3441863] <NSThread: 0x7fed48701040>{number = 11, name = (null)}---17
     2016-03-21 23:30:04.034 01-NSOperation演练(掌握)[17248:3441502] <NSThread: 0x7fed48573e00>{number = 7, name = (null)}---16
     2016-03-21 23:30:05.035 01-NSOperation演练(掌握)[17248:3441849] <NSThread: 0x7fed48426030>{number = 10, name = (null)}---18
     2016-03-21 23:30:05.035 01-NSOperation演练(掌握)[17248:3441863] <NSThread: 0x7fed48701040>{number = 11, name = (null)}---19
     2016-03-21 23:30:06.110 01-NSOperation演练(掌握)[17248:3441849] <NSThread: 0x7fed48426030>{number = 10, name = (null)}---0
     */
}

// MARK: 取消队列里的所有操作
// “取消操作,并不会影响队列的挂起状态”
- (IBAction)cancelAll
{
    // 取消队列的所有操作
    [self.opQueue cancelAllOperations]; // 取消队列的所有操作,会把任务从队列里面全部删除

    NSLog(@"取消所有的操作");

    // 取消队列的挂起状态
    // (只要是取消了队列的操作,我们就把队列处于启动状态。以便于队列的继续)
    self.opQueue.suspended = NO;
    /*
     重要结论:
     1.暂停队列挂起以后,队列里面的操作还在,并且还是可以向队列中加任务的!!
     2.取消操作,会取消挂起状态中的任务,并不会影响队列的挂起状态
     下面手触摸屏幕(会向队列中加一些任务)--->
     2016-03-22 08:35:24.550 01-NSOperation演练(掌握)[756:79773] <NSThread: 0x7fbf186bc710>{number = 2, name = (null)}---0
     2016-03-22 08:35:24.550 01-NSOperation演练(掌握)[756:79771] <NSThread: 0x7fbf18512320>{number = 3, name = (null)}---1
     2016-03-22 08:35:25.572 01-NSOperation演练(掌握)[756:79768] <NSThread: 0x7fbf1852ca50>{number = 4, name = (null)}---2
     2016-03-22 08:35:25.572 01-NSOperation演练(掌握)[756:79771] <NSThread: 0x7fbf18512320>{number = 3, name = (null)}---3

     下面点击暂停---->点击暂停队列挂起以后,队列里面的操作还在,并且还是可以向队列中加任务的!!
     2016-03-22 08:35:26.491 01-NSOperation演练(掌握)[756:79338] 暂停
     2016-03-22 08:35:26.631 01-NSOperation演练(掌握)[756:79768] <NSThread: 0x7fbf1852ca50>{number = 4, name = (null)}---5
     2016-03-22 08:35:26.631 01-NSOperation演练(掌握)[756:79773] <NSThread: 0x7fbf186bc710>{number = 2, name = (null)}---4
     2016-03-22 08:35:50.476 01-NSOperation演练(掌握)[756:79338] 取消所有的操作     ------------>点击取消所有操作
     下面重新触摸屏幕(会向队列中加一些任务)--->
     2016-03-22 08:36:07.320 01-NSOperation演练(掌握)[756:81501] <NSThread: 0x7fbf18540760>{number = 6, name = (null)}---1
     2016-03-22 08:36:07.320 01-NSOperation演练(掌握)[756:81185] <NSThread: 0x7fbf18607790>{number = 5, name = (null)}---0
     2016-03-22 08:36:08.395 01-NSOperation演练(掌握)[756:81500] <NSThread: 0x7fbf18512320>{number = 7, name = (null)}---2
     2016-03-22 08:36:08.395 01-NSOperation演练(掌握)[756:81185] <NSThread: 0x7fbf18607790>{number = 5, name = (null)}---3
     2016-03-22 08:36:09.462 01-NSOperation演练(掌握)[756:81500] <NSThread: 0x7fbf18512320>{number = 7, name = (null)}---4
     2016-03-22 08:36:09.462 01-NSOperation演练(掌握)[756:81552] <NSThread: 0x7fbf1860c8e0>{number = 8, name = (null)}---5
     2016-03-22 08:36:10.530 01-NSOperation演练(掌握)[756:81185] <NSThread: 0x7fbf18607790>{number = 5, name = (null)}---6
     2016-03-22 08:36:10.530 01-NSOperation演练(掌握)[756:81500] <NSThread: 0x7fbf18512320>{number = 7, name = (null)}---7
     2016-03-22 08:36:11.599 01-NSOperation演练(掌握)[756:81185] <NSThread: 0x7fbf18607790>{number = 5, name = (null)}---8
     2016-03-22 08:36:11.599 01-NSOperation演练(掌握)[756:81501] <NSThread: 0x7fbf18540760>{number = 6, name = (null)}---9
     2016-03-22 08:36:12.604 01-NSOperation演练(掌握)[756:81500] <NSThread: 0x7fbf18512320>{number = 7, name = (null)}---11
     2016-03-22 08:36:12.604 01-NSOperation演练(掌握)[756:81185] <NSThread: 0x7fbf18607790>{number = 5, name = (null)}---10
     2016-03-22 08:36:13.650 01-NSOperation演练(掌握)[756:81501] <NSThread: 0x7fbf18540760>{number = 6, name = (null)}---13
     2016-03-22 08:36:13.650 01-NSOperation演练(掌握)[756:81500] <NSThread: 0x7fbf18512320>{number = 7, name = (null)}---12
     2016-03-22 08:36:14.718 01-NSOperation演练(掌握)[756:81552] <NSThread: 0x7fbf1860c8e0>{number = 8, name = (null)}---14
     2016-03-22 08:36:14.718 01-NSOperation演练(掌握)[756:81501] <NSThread: 0x7fbf18540760>{number = 6, name = (null)}---15
     2016-03-22 08:36:15.788 01-NSOperation演练(掌握)[756:81500] <NSThread: 0x7fbf18512320>{number = 7, name = (null)}---16
     2016-03-22 08:36:15.788 01-NSOperation演练(掌握)[756:81552] <NSThread: 0x7fbf1860c8e0>{number = 8, name = (null)}---17
     2016-03-22 08:36:16.862 01-NSOperation演练(掌握)[756:81501] <NSThread: 0x7fbf18540760>{number = 6, name = (null)}---18
     */

}

4-NSOperation任务间依赖

#pragma mark - 高级操作
// MARK: 依赖关系
- (void)dependecy
{
    /**
     例子:
     1. 下载一个小说的压缩包
     2. 解压缩,删除压缩包
     3. 更新UI

     */
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"1. 下载一个小说的压缩包, %@",[NSThread currentThread]);
    }];
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"2. 解压缩,删除压缩包, %@",[NSThread currentThread]);
    }];
    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"3. 更新UI, %@",[NSThread currentThread]);
    }];

    // 指定任务之间的依赖关系 -- 依赖关系可以跨队列(可以在子线程下载完,到主线程更新UI)
    [op2 addDependency:op1];
    [op3 addDependency:op2];

    // 注意点:一定不要出现循环依赖关系
//    [op1 addDependency:op3];

    // waitUntilFinished 类似GCD的调度组的通知
    // NO 不等待,会直接执行  NSLog(@"come here");
    // YES 等待上面的操作执行结束,再 执行  NSLog(@"come here")
    [self.opQueue addOperations:@[op1, op2] waitUntilFinished:YES];

    // 在主线程更新UI
    [[NSOperationQueue mainQueue] addOperation:op3];
    NSLog(@"come here");
    /*
     2016-03-22 10:18:37.780 01-NSOperation演练(掌握)[1106:331553] 1. 下载一个小说的压缩包, <NSThread: 0x7f932bf04600>{number = 5, name = (null)}
     2016-03-22 10:18:37.781 01-NSOperation演练(掌握)[1106:331556] 2. 解压缩,删除压缩包, <NSThread: 0x7f932bc28fc0>{number = 6, name = (null)}
     2016-03-22 10:18:37.782 01-NSOperation演练(掌握)[1106:326977] come here
     2016-03-22 10:18:37.782 01-NSOperation演练(掌握)[1106:326977] 3. 更新UI, <NSThread: 0x7f932bc064d0>{number = 1, name = main}
     */
}

5-线程间通信(最重要的代码)

#pragma mark - 基本使用
// MARK: 线程间通信(最重要的代码)
- (void)opDemo5
{
    NSOperationQueue *q = [[NSOperationQueue alloc]init];

    [q addOperationWithBlock:^{
        NSLog(@"耗时操作....%@", [NSThread currentThread]);

        // 在主线程更新UI
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            NSLog(@"更新UI....%@", [NSThread currentThread]);
        }];
    }];
    /*
     2016-03-21 18:53:09.477 01-NSOperation演练(掌握)[3342:2751378] 耗时操作....<NSThread: 0x7fff0bd4e9f0>{number = 3, name = (null)}
     2016-03-21 18:53:09.477 01-NSOperation演练(掌握)[3342:2750846] 更新UI....<NSThread: 0x7fff0bd08c20>{number = 1, name = main}
     */

}
时间: 2024-10-07 03:07:35

NSOperation一些总结的相关文章

多线程之-NSOperation

多线程之-NSOperation NSOperation是个抽象类,并不具备封装操作的能力,必须使用它的子类 NSInvocationOperation 如果直接执行NSInvocationOperation中的操作, 那么默认会在主线程中执行 // 创建队列 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 创建操作 NSInvocationOperation *operation = [[NSInvocationOpe

IOS中的多线程【二】— NSOperation和NSOperationQueue

NSOperationQueue是一套基于Objective-c语言的API. GCD与NSOperationQueue的优缺点: NSOperationQueue:比较安全 GCD:没有NSOperationQueue安全,但使用起来简单,快速,还提供了一些操控底层的方法.实际开发中还是以GCD为主. NSOperationQueue实现多线程流程 1.定义一个任务队列. 2.定义一个任务. 3.把任务添加到队列中.一旦任务被添加到队列中,任务会马上被调度执行. 任务队列(NSOperatio

iOS开发NSOperation 三:操作依赖和监听以及线程间通信

一:操作依赖和监听 #import "ViewController.h" @interface ViewController () @end @implementation ViewController /** * 1:NSOperation的使用:1:先创建队列NSOperationQueue:若不创建队列直接封装任务则默认在当前线程中串行执行任务,其队列分为两种主队列和非主队列,主队列和GCD中的主队列一样[NSOperationQueue mainQueue],而alloc in

线程2 NSOperation 抽像类的使用

// // ZYOperationViewController.h // Thread // // Created by yejiong on 14 // // ZYOperation.h // Thread // // Created by yejiong on 14/11/4. // Copyright © 2014年 zzz. All rights reserved. // #import <Foundation/Foundation.h> @interface ZYOperation

iOS中用GCD和NSOperation多个异步操作的关联

在iOS实际开发中,我们可能会遇到下面的场景:有以下四个操作A,B,C,D.要求A,B,C在子线程中执行,当A,B,C执行完毕之后回到主线程执行操作D,ABC之间可能会有相互依赖的关系,我们可以通过GCD和NSOperation都可以实现这样的需求. 1.GCD // 用GCD - (void)useGCD { // 1.1可以创建一个全局并发队列,A,B,C操作会在子线程中并发执行,ABC不存在先后执行顺序 // dispatch_queue_t quque=dispatch_get_glob

GCD和NSOperation 的概念,用法及之间的区别

CGD与NSOperation的区别 gcd是基于c的底层api,NSOperation属于object-c类.相对于gcd:1,NSOperation拥有更多的函数可用,具体查看api.2,在NSOperationQueue中,可以建立各个NSOperation之间的依赖关系.3,有kvo,可以监测operation是否正在执行(isExecuted).是否结束(isFinished),是否取消(isCanceld).4,NSOperationQueue可以方便的管理并发.NSOperatio

step 7 NSOperation(高级/GCD对比)

高级演练 全局队列 /// 全局操作队列,统一管理所有的异步操作 @property (nonatomic, strong) NSOperationQueue *queue; - (NSOperationQueue *)queue { if (_queue == nil) { _queue = [[NSOperationQueue alloc] init]; } return _queue; } 最大并发操作数 /// MARK: - 最大并发操作数 - (void)opDemo1 { // 设

iOS开发-NSOperation与GCD区别

Mac OS X 10.6及iOS4.0之后导入了可以使全体线程更高效运行,并且使并行处理应用更易开发的架构,GCD(Grand Central  Dispatch),同时引入的还有Run Loop,线程(包括Cocoa和POSIX)和Operation.GCD拥有非常轻量级的工作单元和并发方式,并且由系统决定其最佳调度方式.这个时候出现了一个问题,NSOperation如何处理呢? 其实我们在通过NSOperation和GCD进行开发过程中,会发现两者执行的方式有许多相似之处,NSOperat

多线程----NSOperation

NSOperation是Cocoa中的一个抽象类,用来封装单个任务和代码执行一项操作,由于是抽象类,所以不能直接实例化使用,必须定义子类继承该抽象类来实现, 使用NSOperation的方式有两种: 一种是用定义好的两个子类: NSInvocationOperation 和 NSBlockOperation,有相关的使用方法. NSOperation的子类NSInvocationOperation提供了一套简单的多线程编程方法,是IOS多线程编程中最简单的一种实现方式. 另一种是继承NSOper

NSOperation开启线程情况分析

如果NSOperation中只有一个任务,且调用start方法不会开启线程,start默认在当前线程执行. 如果NSOperation中只有一个任务,添加到队列当中会开启线程,如果是主队列则不会开启新的线程 一个NSOperation中添加了多个任务,且调用start方法,开启新的线程. 多个NSOperation,且每个NSOperation中只有一个任务,且每个NSOperation调用start方法 ,不会开启新的线程. 多个任务,添加到一个队列当中, 多个任务添加到主队列