I know I am going to get the "Should have used OperationQueues" but I had issues with it on the original implementation.. and infact was getting the same error as this. Both have confused me but this one even more so.
I have an add method which is syncronized on the operations
and the worker is syncronized on that too.
The issues is that the objects getting picked off (at least to my knowledge) shouldn't be on the list yet. It then calls execute on the same one twice and skips the first one.
So if A B C was added. It might execute A C C and B doesnt even make an appearance. No other class can see operations
and the only thing that adds to it is addOperation
Some output from the program.
[Queue Manager] Adding new operation [ 111 ] is <SendOperation: 0x1dd5c510>
[Queue Manager] executing operation [ 112 ] is <SendOperation: 0x1dd5c510>
[Operation] executing [ 112 ]
[Queue Manager] Adding new operation [ 112 ] is <SendOperation: 0x1dd266e0>
[Queue Manager] executing operation [ 112 ] is <SendOperation: 0x1dd266e0>
It gets the address right. But the number wrong. The number is just an int in the Operation object. It is only ever sen on construction. It has not setters, or way of been modified.
What's going on here?
Looks like somehow im duplicating it in to the address of another one?
#import "MyOperationQueue.h"
#import "Operation.h"
@implementation MyOperationQueue
NSMutableArray *operations;
NSCondition *condition;
-(id) init {
self = [super init];
if(self != nil) {
operations = [[NSMutableArray alloc] init];
condition = [[NSCondition alloc] init];
}
return self;
}
- (void) start{
[self performSelectorInBackground:@selector(run) withObject:self];
}
-(void)run{
while(YES){
[condition lock];
[condition wait];
NSMutableArray *buffer = [[NSMutableArray alloc] init];
@synchronized(operations){
while([operations count] != 0 ) {
Operation *operation = [operations objectAtIndex:0];
[operations removeObject:operation];
NSLog(@"[Queue Manager] executing operation %i is %@",[operation getNumber],operation);
[operation execute];
}
}
[condition unlock];
}
}
-(void)addOperation:(id)operation{
@synchronized(operations){
NSLog(@"[Queue Manager] Adding new operation [ %i ] is %@",[operation getNumber],operation);
[operations addObject:(operation)];
}
[sendCondition signal];
}
@end
@implementation Operation
int idNumber;
-(id) initWithIdNumber:(int)idNumber_{
self = [super init];
if( self ) {
idNumber = idNumber_;
}
return self;
}
- (void) execute{
NSLog(@"[Operation] executing [ %i ]",idNumber);
}
-(int) getIdNumber{
return idNumber;
}
@end