2016-09-29 156 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];」。 –