TheObjCGuy
TheObjCGuy

Reputation: 687

NSoperation reverse dependencies

In one of my apps i have a NSOperationQueue and some subclass of NSOperations. I've added some dependencies so, the operation A not start until operation B finish.

I need to cancel the operation A if the operation B fails, but from inside the operation B i don't have any list of operation who dependes on the current operation.

I will try to add some weak properties on my subclass, like

@property (nonatomic, weak) NSArray *dependsOnMe;

but i'm afraid to generate some strange loop.

thanks

Upvotes: 2

Views: 257

Answers (3)

Jean Le Moignan
Jean Le Moignan

Reputation: 22236

Although I'm way late in the discussion, here's what I've written to help me get reverse dependencies for an NSOperation. If you know the queue used, then you can use this extension:

extension NSOperationQueue {
    func reverseDependenciesForOperation(op: NSOperation) -> [NSOperation] {
        return operations.filter { $0.dependencies.contains(op) }
    }
}

Upvotes: 2

Rui Peres
Rui Peres

Reputation: 25907

 I've added some dependencies so, the operation A not start until operation B finish.

And:

I need to cancel the operation A if the operation B fails

You see where this is going?

What would make sense, would be from B to cancel B if B fails. But again, A will only start when B finishes.


From here:

Dependency: you can make an operation dependent on other operations. Any operation can be dependent on any number of operations. When you make operation A dependent on operation B, even though you call “start” on operation A, it will not start unless operation B isFinished is true. For example:

MyDownloadOperation *downloadOp = [[MyDownloadOperation alloc] init]; // MyDownloadOperation is a subclass of NSOperation
MyFilterOperation *filterOp = [[MyFilterOperation alloc] init]; // MyFilterOperation  is a subclass of NSOperation

[filterOp addDependency:downloadOp];

Upvotes: 0

Warren Burton
Warren Burton

Reputation: 17372

Theres a bit of missing info here. Like when you construct B , do you also construct A?

Is there a need to do this? Why not construct A on the successful completion of B?

You could use use a delegate protocol if its a one to one dependancy from B to A

@protocol DependantOperationCompletion <NSObject>

-(void)operationDidFail;

@end

@interface BOperation

@property (weak) id<DependantOperationCompletion> delegate;

@end

and

@interface AOperation:NSOperation <DependantOperationCompletion> 

...

@end

then when you construct the operations set up A as a delegate of B

bOpInstance.delegate = aOpInstance;

Alternatively use the "Shout out the window" approach and post a notification if B fails. A listens for the notification.

within B...

-(void)handleFailure
{
    [[NSNotificationCenter defaultCenter] postNotificationName:BTypeOpDidFailNotification object:self userInfo:someInfoOrNil]

}

within A...

-(void)setupWithBOp:(BOperation *)binstance
{

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(ohNoBHazFailed:) name:BTypeOpDidFailNotification object:binstance];

}

Remember to remove A as observer on dealloc

Upvotes: 0

Related Questions