Reputation: 2061
I have two NSOperation
objects "A" and "B", and want to use dependency as I need to let complete "B" first and then start "A".
- (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];
}
Expected Output:
B
A
But sometimes:
A
B
But I want to complete first B and then need to start A. Please help me on it.
Upvotes: 1
Views: 696
Reputation: 3573
op1.addDependency(op2);
or check this also
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];
Upvotes: 1
Reputation: 2061
I could able to achieve it by using NSBlockOperation
class instead of NSOperation
. Here is a sample code snippet.
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
Upvotes: 0
Reputation: 4096
Here completion blocks are not part of the queue instead they run outside of the Operation Queue on another thread. Thus Operation A's completionBlock will run at the same time as Operation B.
According to your ques you are using the completionBlocks to pass information from operation A to B.
Here are some solution:
Give B references to all the A's (not weak) so when B runs it can pick the results from operation A.
keep all the A operation around until B runs, then recreate your Completion Block's as another NSOperation
see code below:
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];
Upvotes: 1