美文网首页iOS
多线程研究二:NSBlockOperation通过判断isCan

多线程研究二:NSBlockOperation通过判断isCan

作者: 独孤流 | 来源:发表于2019-02-19 16:52 被阅读1次
上一篇:多线程研究一:NSOperation实现GCD group依赖

本文Sample Github: MultithreadSample

前言

在多线程处理中,有时候会遇到虽然已经取消了队列里的所有Operation,但是如果Operation已经开始执行,cancle就已经不起作用了,这个会导致数据错乱乃至APP崩溃闪退的异常问题

解决方法:利用NSBlockOperation执行block时,将该NSBlockOperation使用__block到block里,然后对当前的Operation判断是否已经被取消,具体代码实现如下:

Objective-C实现方式

+ (void) testOperationCancleOperationBlock
{
    // 打印当前线程
    //NSLog(@"###oc-operation1-begin-currentThread---%@",[NSThread currentThread]);
    NSMutableArray *ops = [NSMutableArray array];
    // 需要循环遍历添加执行任务的场景
    for (int i=0;i<10;i++) {
        int temps = (arc4random() % 5) + 1;
        NSBlockOperation *op = [LFCustomBlockOperationOC new];
        __weak typeof(NSBlockOperation) *weakOp = op;
        [op addExecutionBlock:^{
            NSLog(@"###oc-cancle-aaa %d %@ isCancelled:%@",i,weakOp,weakOp.isCancelled?@"true":@"false");
            if (weakOp.isCancelled){
                return ;
            }
            [NSThread sleepForTimeInterval:temps];
            NSLog(@"###oc-cancle-bbb %d %@ isCancelled:%@",i,weakOp,weakOp.isCancelled?@"true":@"false");
            if (weakOp.isCancelled){
                return ;
            }
            NSLog(@"###oc-cancle-ccc i:%d-wait:%d-thread:%@",i,temps,NSThread.currentThread);
        }];
        [ops addObject:op];
    }
    // 不是遍历添加的需要单独添加的任务
    TestGCDOperationOC *target = [TestGCDOperationOC new];
    NSOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:target selector:@selector(hello:) object:@"1"];
    [ops addObject:op1];
    // 其他Operation都执行完后再执行的Operation
    NSOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"###oc-cancle- ++++++thread:%@",NSThread.currentThread);
        });
    }];
    // 最后执行的任务对其他所有任务都添加依赖
    for (NSOperation *op in ops) {
        [op2 addDependency:op];
    }
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [ops addObject:op2];
    // 添加到任务队列中执行
    [queue addOperations:ops waitUntilFinished:false];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [queue cancelAllOperations];
    });
}

Swift实现方式

 class func testOperationCancleOperationBlock() -> Void
    {
        var ops: [Operation] = []
        // 需要循环遍历添加执行任务的场景
        for i in 0..<10 {
           let temps:Int = Int(arc4random_uniform(3))+1
             let operation: BlockOperation = LFCutomeBlockOperationSwift()
            weak var weakOpe = operation
            operation.addExecutionBlock {
                print("###swift-cancle-aaa i:\(i)-wait:\(temps)-isCancle:\(String(describing: weakOpe?.isCancelled))")
                if weakOpe?.isCancelled ?? false {
                    return
                }
                sleep(UInt32(temps))
                print("###swift-cancle-bbbx i:\(i)-wait:\(temps)-isCancle:\(String(describing: weakOpe?.isCancelled))")
                if weakOpe?.isCancelled ?? false {
                    print("###swift-cancle-bbby i:\(i)-wait:\(temps)-isCancle:\(String(describing: weakOpe?.isCancelled))")
                    return
                }
                print("###swift-cancle-ccc i:\(i)-wait:\(temps)-thread:\(Thread.current)")
            }
            ops.append(operation)
        }
        // 不是遍历添加的需要单独添加的任务
        let op1 = BlockOperation {
            print("###swift-cancle -------\(Thread.current)")
        }
        ops.append(op1)
        let op2 = BlockOperation {
            DispatchQueue.main.async {
                print("###swift-cancle +++++-\(Thread.current)")
            }
            
        }
        // 最后执行的任务对其他所有任务都添加依赖
        for op in ops {
            op2.addDependency(op)
        }
        ops.append(op2)
        let queue = OperationQueue()
        // 添加到任务队列中执行
        queue.addOperations(ops, waitUntilFinished: false)
        DispatchQueue.global().asyncAfter(deadline: .now()+2) {
            queue.cancelAllOperations()
        }
    }

相关文章

网友评论

    本文标题:多线程研究二:NSBlockOperation通过判断isCan

    本文链接:https://www.haomeiwen.com/subject/zcefyqtx.html