iOS多线程学习之NSOperation(二)

  接着上次讲,现在有一个需求:
    /**
     *  假设有A、B、C三个操作,要求:
     *  1.三个操作异步执行
     *  2.但是执行步骤为A,B,C
     *

     */

     这时我们就要用到依赖关系了,这是GCD所没有的

- (void)viewDidLoad {
    [super viewDidLoad];

    //[self invocationQueue];
   // [self blockQueue];
   // [self opeationQueue];
    
    /**
     *  假设有A、B、C三个操作,要求:
     *  1.三个操作异步执行
     *  2.但是执行步骤为A,B,C
     *  这时我们就要用到依赖关系了
     *
     */
    
    [self createQueueDepend];
    
}

- (void)createQueueDepend {

    NSOperationQueue * queue = [[NSOperationQueue alloc] init];
    
    NSBlockOperation * operationA = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"A");
    }];
    NSBlockOperation * operationB = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"B");
    }];
    NSBlockOperation * operationC = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"C");
    }];
    
    [operationC addDependency:operationB];
    [operationB addDependency:operationA];
    [queue addOperation:operationA];
    [queue addOperation:operationB];
    [queue addOperation:operationC];
    
}

设置依赖关系只要调用addDependency:这个API就好了,关系是C依赖于B,B依赖于A,且都是单向的,B操作要等A操作完成才可以,而C操作要等B操作完成才可以,,换句话说依赖把并行关系弄成了串行关系,再就是不能写成相互依赖,要不然,你等我,我等你,大家都成了等待状态,往下还怎么执行啊,直接死掉了线程。

上面也是面试会问到的,异步怎么有顺序完成,当然也可以用优先级完成,这个操作完成的比较简单,而GCD完成就要麻烦一些了。

另外可以在不同的queue的NSOperation之间创建依赖

- (void)createQueueDepend {

    NSOperationQueue * queue = [[NSOperationQueue alloc] init];
    
    NSOperationQueue * queue1 = [[NSOperationQueue alloc] init];
    
    NSBlockOperation * operationA = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"A");
    }];
    NSBlockOperation * operationB = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"B");
    }];
    NSBlockOperation * operationC = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"C");
    }];
    
    NSBlockOperation * operationa = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"a");
    }];
    
    [operationC addDependency:operationB];
    [operationB addDependency:operationA];
    [operationA addDependency:operationa];
    
    [queue addOperation:operationA];
    [queue addOperation:operationB];
    [queue addOperation:operationC];
    [queue1 addOperation:operationa];
    
}

(二)操作的监听

其实意义不太大,这句话是MJ说的,我还没用过太多,这句话观点保留

- (void)createQueueDepend {

    NSOperationQueue * queue = [[NSOperationQueue alloc] init];
    
    NSOperationQueue * queue1 = [[NSOperationQueue alloc] init];
    
    NSBlockOperation * operationA = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"A");
        /**
         *  其实下面的完成操作大可不必写,因为可以在下面继续写么
         */
        NSLog(@"AA");
    }];
//    [operationA setCompletionBlock:^{
//        /**
//         *  这里放打印A后要执行的任务
//         */
//        NSLog(@"AA");
//    }];
    NSBlockOperation * operationB = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"B");
    }];
    NSBlockOperation * operationC = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"C");
    }];
    
    NSBlockOperation * operationa = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"a");
    }];
    
    [operationC addDependency:operationB];
    [operationB addDependency:operationA];
    [operationA addDependency:operationa];
    
    [queue addOperation:operationA];
    [queue addOperation:operationB];
    [queue addOperation:operationC];
    [queue1 addOperation:operationa];
    
}

//线程之间的通信

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    [self loadImageView];
}

- (void)loadImageView {

    NSOperationQueue * queue = [[NSOperationQueue alloc] init];
    [queue addOperationWithBlock:^{
        UIImage * image = [self callMethodWithUrl:@"http://pic2.52pk.com/files/130701/1283568_093144_1_lit.jpg"];
        // 回到主线程刷新UI(三种方式)
//        [self performSelectorOnMainThread:@selector(refeshUI:) withObject:image waitUntilDone:NO];
        
//        dispatch_async(dispatch_get_main_queue(), ^{
//           self.imageView.image = image; 
//        });
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            self.imageView.image = image;
        }];
    }];
}

(三)队列的取消、暂停、恢复

(1)- (void)cancelAllOperations;  //取消所有操作,也就是删除了后面所有要执行的任务,不可恢复

(2)[queue setSuspended:YES]; //暂停后面要执行的操作任务,可恢复

(3)[queue setSuspended:NO]; //恢复后面要执行的操作任务



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值