I am adding operations to the queue using something like this
NSInvocationOperation *operation0 = [[NSInvocationOperation alloc]
initWithTarget:self
selector:@selector(doStuff1)
object:nil];
[queue addOperation:operation0];
[operation0 release];
NSInvocationOperation *operation1 = [[NSInvocationOperation alloc]
initWithTarget:self
selector:@selector(doStuff2)
object:nil];
[queue addOperation:operation1];
[operation1 release];
NSInvocationOperation *operation2 = [[NSInvocationOperation alloc]
initWithTarget:self
selector:@selector(doStuff3)
object:nil];
[queue addOperation:operation2];
[operation2 release];
The queue is set to do just one operation at a time. So it will run the 3 methods without delay, one after another. Is that a way to add a small delay, lets say 0.5 seconds or whatever between each operation, so instead of running
doStuff1
doStuff2
doStuff3
the queue would do
doStuff1
sleep for X seconds
doStuff2
sleep for X seconds
doStuff3
?
thanks.
Using sleep is a big waste of a thread. This is bad in the Ghostbusters' sense.
If you need a queue that executes its operations non-concurrently i.e. sequentially you can simpy set its maxConcurrentOperationCount variable to 1.
queue.maxConcurrentOperationCount = 1;
To pause between operations you could do two different things:
a) Delay the queueing of each operation:
//loop over the operations to be queued with and index
double delayInSeconds = 2.0 * index;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
queue.addOperation(operation at index);
});
This will queue all operations without blocking.
b) Every operation has to implement
- (BOOL)isFinished
as you probably already know.
If your operation is "done" just delay setting its "done" variable by your desired delay. Use something like:
// Operation is done with its work, but we tell the Queue only after 2 seconds, so the queue will start the next operation later
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
__weak __typeof(self)weakSelf = self;
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[weakSelf willChangeValueForKey:@"isExecuting"];
[weakSelf willChangeValueForKey:@"isFinished"];
weakSelf.executing = NO;
weakSelf.finished = YES;
[weakSelf didChangeValueForKey:@"isFinished"];
[weakSelf didChangeValueForKey:@"isExecuting"];
});
Variant a) guarantees a pause between starting times of operations. Variant b) guarantees a pause between the end of an operation and the start of a next operation.
Without extra code, you can't really guarantee that your NSOperations will run in serial - if Apple release a multiprocessor iOS device, it will run multiple operations in parallel. So firstly, you should set up the dependency chain between your operations. I would suggest that you achieve this using NSOperation's - (void)addDependency:(NSOperation *)operation
. You could also roll your own fancy locking code...
You can then add a sleep(5) to the end of each of your doStuff methods. If you need the sleep outside the doStuff methods, create a sleep NSOperation:
- (void)sleepOperationBody; {
sleep(0.5f);
}
NSInvocationOperation *operation1 = [[NSInvocationOperation alloc]
initWithTarget:self
selector:@selector(sleepOperationBody)
object:nil];
That said, without knowing in more detail what you need to happen, I think you perhaps just need one NSOperation that combines all three tasks and puts a sleep between them. That would certainly be simpler code.
I have two ways to do such thing.
First: Let the current thread to sleep on the tail of doStuff1, doStuff2, and doStuff3.
Second: Sub-class NSOperation and override the method -(void)main. You can init a custom NSOperation with parameters of target and action like following:
-(id)initWithTarget:(id)target action:(SEL)action;
And execute this action of target in the -(void)main by
[target performSelector:action];
[NSThread sleepForTimeInterval:0.05];
you can do like following manner
[operation0 addDependancy:operation1];
[operation1 addDependancy:operation2];
and now add [NSThread sleepforTimeInterval:5] to at the end of each task
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With