Mark A. Donohoe
Mark A. Donohoe

Reputation: 30368

Can you use cross-queue dependencies for NSOperation objects?

Is it possible/legal to have cross-queue dependency operations?

Consider the following...

let operationA = NSBlockOperation(block: someBlock)
let operationB = NSBlockOperation(block: someOtherBlock)

let operationC = NSBlockOperation(block: finalBlock)
operationC.addDependency(operationA)
operationC.addDependency(operationB)

OperationQueue().addOperation(operationC)
OperationQueue().addOperation(operationA)
OperationQueue().addOperation(operationB)

I don't see anywhere in the docs that says this is a restricted usage, but I'm also not sure if such thing is possible/supported. (Note: I'm also not saying if this is good practice or not. Just trying to 'poke' the language to see what's possible as food for thought.)

Upvotes: 4

Views: 689

Answers (1)

malhal
malhal

Reputation: 30571

Yes

"The other neat thing about dependencies is that they are not limited by operation queues. Now, what do I mean by this? If you have two operation queues in your application, operations in the first queue can be dependent on the operations in the second queue."

https://developer.apple.com/videos/play/wwdc2015/226/

Here is an example you can try:

NSOperationQueue *queue1 = [[NSOperationQueue alloc] init];

NSBlockOperation *a1 = [[NSBlockOperation alloc] init];

NSBlockOperation *a2 = [[NSBlockOperation alloc] init];

[a1 addExecutionBlock:^{
    NSLog(@"a1");
    
    NSOperationQueue *queue2 = [[NSOperationQueue alloc] init];
    
    NSBlockOperation *b1 = [[NSBlockOperation alloc] init];
    
    NSBlockOperation *b2 = [[NSBlockOperation alloc] init];
    
    [b1 addExecutionBlock:^{
        NSLog(@"b1");
    }];
    
    [b2 addExecutionBlock:^{
        NSLog(@"b2");
    }];

    [a2 addDependency:b2]; // makes this inner queue finish first
    
    [b2 addDependency:b1];
    
    [queue2 addOperations:@[b1, b2] waitUntilFinished:NO];
    
}];

[a2 addExecutionBlock:^{
    NSLog(@"a2");
}];

[a2 addDependency:a1];

[queue1 addOperations:@[a1, a2] waitUntilFinished:NO];

Outputs:

2017-01-08 00:27:03.019497 OpTest[26141:36238589] a1
2017-01-08 00:27:03.019621 OpTest[26141:36238621] b1
2017-01-08 00:27:03.019721 OpTest[26141:36238589] b2
2017-01-08 00:27:03.019773 OpTest[26141:36238621] a2

As you can see the [a2 addDependency:b2] line allows a sub-queue of operations to finish within the main queue.

Upvotes: 3

Related Questions