I have some iPhone SDK 4.0 code which initializes an NSOperationQueue
and then adds three classes (ClassA
, ClassB
, and ClassC
) to run one after the other. ClassA
, ClassB
, and ClassC
are all sub-classes of NSOperation
.
The relevant code is included below.
ClassA *classA = [[ClassA alloc] init];
ClassB *classB = [[ClassB alloc] init];
ClassC *classC = [[ClassC alloc] init];
[classB addDependency:classA];
[classC addDependency:classB];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:classA];
[queue addOperation:classB];
[queue addOperation:classC];
[classA release];
[classB release];
[classC release];
[queue release];
The reason for the dependencies is because classB
should only run if classA
completes its operation successfully. Likewise, classC
should only run if classB
completes successfully.
At the moment I am having difficulty figuring out how to prevent, for example, classB
from running if classA
does not complete successfully. Continuing with this example, I was thinking of somehow evoking [NSOperationQueue cancelAllOperations]
from within classA
but I don't know how to get a handle on the parent NSOperationQueue
from within classA
(which is an NSOperation
sub-class). This was just my initial thought, so I would be open to any other better suggestions for achieving the same outcome!
There is conditional code within each of the classes to determine whether they have completed properly - at the moment they are just NSLogging "Success" or "Fail" to the Console for debugging purposes. In a perfect world I would just like to be able to replace the NSLog(@"Fail")
statement in each class with some code which will stop all of the other classes in the NSOperationQueue from running.
Any suggestions would be most welcome (and appreciated).
You could set a property in classA :
@property (readonly) BOOL completedSucessfully;
and set this to YES at the end of classA's main method.
Then, just check it at the start of classB.
- (void)main {
if (NO == [[dependencies objectAtIndex:0] completedSucessfully])
return;
Now, classB will just stop if classA reports failure.
NB You will probably need more error checking that in the example above i.e. making sure that you have dependencies, checking that it's the correct class etc.
- (void)main {
for (id *temp in [self dependencies])
if ([temp isKindOfClass:[ClassA class]])
if (NO == [(ClassA *)temp finishedSucessfully])
return;