2016-09-29 108 views
1

我有两个NSOperation对象“A”和“B”,并且想要使用依赖关系,因为我需要首先完成“B”,然后启动“A”。“addDependency”在iOS中无法正常工作

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    NSOperationQueue *myQueue = [NSOperationQueue new]; 
    NSOperation *op1 = [[NSOperation alloc] init]; // Its a background(concurrent) thread. 
    op1.completionBlock =^{ 
     NSLog(@"A"); 
    }; 

    NSOperation *op2 = [[NSOperation alloc] init]; 
    op2.completionBlock =^{ 

     NSLog(@"B"); 
    }; 
    [op1 addDependency:op2]; 
    [myQueue addOperation:op1]; 
    [myQueue addOperation:op2]; 
} 

预期输出:

B 
A 

但有时:

A 
B 

但我想完成第一次B,然后需要开始答:请帮我就可以了。

+0

你能展示如何调用这段代码吗?它是否被连续调用,就像在循环中一样? – danh

+0

@danh,不在循环中。我只是放在“viewDidLoad”方法中。 –

+0

我明白了。这吹了我的理论。你有办法可靠地重现乱序行为吗?只是为了好玩,你可以添加'[myQueue waitUntilAllOperationsAreFinished];' – danh

回答

0

我可以能够通过使用NSBlockOperation类,而不是NSOperation实现它。这是一个示例代码片段。

NSOperationQueue *myQueue = [NSOperationQueue new]; 
    NSBlockOperation *blockOp1 = [[NSBlockOperation alloc] init]; 
    [blockOp1 addExecutionBlock:^{ 

     NSLog(@"1"); 
    }]; 

    NSBlockOperation *blockOp2 = [[NSBlockOperation alloc] init]; 
    [blockOp2 addExecutionBlock:^{ 

    NSLog(@"2"); 
    }]; 

    [blockOp1 addDependency:blockOp2]; 
    [myQueue addOperation:blockOp1]; 
    [myQueue addOperation:blockOp2]; 

    Output: 2 
      1 
1
  1. 首先创建操作OP1
  2. 如果操作OP2提供的数据不可用,创建操作OP2
  3. 使操作OP1依赖于操作OP2。即。像op1.addDependency(op2);

或检查,这也

NSOperationQueue *queue = [[NSOperationQueue alloc] init]; 
    NSOperation *op1; 
    NSOperation *op2; 

    //... initialize op1 and op2 however you please ... 

    [op1 setCompletionBlock:^{ 
     if ([op1 satisfiesSomeCriteria]) { 
      [queue addOperation:op2]; 
     } 
    }]; 
[queue addOperation:op1]; 
+0

谢谢你的回复。如果我们像上面那样做,那么“addDependency”方法的用途/目的是什么? –

1

这里完成块不是队列的一部分,而不是他们在另一个线程的操作队列之外运行。因此操作A的completionBlock将在同一时间运行的操作B.

根据您的疑问句您正在使用的completionBlocks通过从操作的信息B.

这里有一些解决方案:

  • 给到B引用的所有A的(不弱),所以当B运行时,它可以选择从操作A.结果

  • 保留所有A操作身边,直到乙运行,然后重新创建完成布洛克的另一个012下面见代码:


NSOperation *operA = [NSBlockOperation blockOperationWithBlock:^{ // do stuff 
}]; 

NSOperation *operationATail = [NSBlockOperation blockOperationWithBlock:^{ // do completionBlock stuff 
}]; 

// First bullet point 
[operationATail addDependency:operA]; 

// Second bullet point 
[operationB addDependency:operationATail]; 

[self.queue addOperations:@[operA, operationATail, operationB] waitUntilFinished:NO]; 
+0

我能够通过使用“NSBlockOperation”得到它,但我想通过“NSOperation”来完成。无需再添加依赖关系“[operationB addDependency:operationATail];”。 –