Reputation: 2601
I would like to add a dispatch_async sequentially but I would like them not to be launched randomly. I would like for example :
dispatch_async 1 begins...
dispatch_async 1 ends.
dispatch_async 2 begins...
dispatch_async 2 ends.
dispatch_async 3 begins...
dispatch_async 3 ends.
I need to update a sqlite, and the informations in the first dispatch are necessary for the second dispatch...
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(@"%@",[connection currentRequest]);
NSLog(@"connectionDidFinishLoading");
NSError* error;
NSString *responseKey = [self getResponseKey:connection];
NSDictionary* response = [NSJSONSerialization JSONObjectWithData:[receivedData objectForKey:responseKey] options:kNilOptions error:&error];
//NSLog(@"%@", response);
if (error)
{
NSLog(@"Error: %@", error);
NSLog(@"Error: Response strange format, not an NSArray and not a NSString!\n%@", [[NSString alloc] initWithData:[receivedData objectForKey:responseKey] encoding:NSUTF8StringEncoding]);
}
NSLog(@"connection url : %@", connection.currentRequest.URL);
if ([[NSString stringWithFormat:@"%@", [connection currentRequest]] rangeOfString:@"getSynchroGuest?"].location != NSNotFound)
{
NSLog(@"response success");
if ([[response valueForKey:@"lignes"] isKindOfClass:[NSArray class]])
{
if ([[response valueForKey:@"lignes"] count] > 0)
{
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
//Background Thread
[self fillDataBaseWithDict:response];
nbTotal = nbTotal + PACKET_FOR_SYNC;
[self WebServiceSynchroGuest:self.activityIndicator withSynchroBtn:synchroBtn withNbTotal:nbTotal];
});
}
}
...
Thanks in advance.
SOLUTION:
dispatch_async(serialDispatchQueue, ^{
[self fillDataBaseWithDict:response];
nbTotal = nbTotal + PACKET_FOR_SYNC;
dispatch_async(dispatch_get_main_queue(), ^(void){
[self WebServiceSynchroGuest:self.activityIndicator withSynchroBtn:synchroBtn withNbTotal:nbTotal];
});
});
Upvotes: 2
Views: 611
Reputation: 303
You can put all dispatch_async as a Serial Queue and execute one by one
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {
// block1
NSLog(@"Block1");
[ NSThread sleepForTimeInterval:5.0];
NSLog(@"Block1 End");
});
dispatch_group_async(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {
// block2
NSLog(@"block 2");
[ NSThread sleepForTimeInterval:10.0];
NSLog(@"Block2 End");
});
dispatch_group_async(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {
// block3
NSLog(@"block 3");
[ NSThread sleepForTimeInterval:15.0];
NSLog(@"Block3 End");
});
dispatch_group_notify(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {
// block4
NSLog(@"block 4");
[ NSThread sleepForTimeInterval:20.0];
NSLog(@"Block4 End");
});
Upvotes: 1
Reputation: 667
add code like this
You can set PRIORITY as well.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
});
});
Upvotes: 0
Reputation: 16650
To take your Q literally, you have to nest the calls:
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^(void)
{
// do some work
…
// finished here
// The next async code
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^(void)
{
// do some work
…
// finished here
// and so on
}
}
But you should really consider to use a custom serial queue or NSOperation
et al.
With a serial Q:
dispatch_queue_t stepByStepQueue = dispatch_queue_create("com.you.taks", NULL);
dispatch_async(stepByStepQueue,
^(void)
{
// Step
});
dispatch_async(stepByStepQueue,
^(void)
{
// By
});
dispatch_async(stepByStepQueue,
^(void)
{
// Step
});
Upvotes: 2
Reputation: 8424
define your own serial queue
and add code like this
dispatch_queue_t yourSerialQueue = dispatch_queue_create("com.testcompany.testproduct.testserialqueue", DISPATCH_QUEUE_SERIAL);
dispatch_async(yourSerialQueue, ^{ /* first task */ });
dispatch_async(yourSerialQueue, ^{ /* second task to be executed after first task */ });
serial queue guarantees that the tasks will be exevuted in the order they are submitted and in a serial manner(one at a time)
Upvotes: 3
Reputation: 5190
Best approach would be to use NSOperations & add them in queue.so it would be called in sequence of completion
But if you want to do it in same way then define completion blocks & add your dispatch_async2 & dispatch_Async3 in completion blocks & call those completion blocks in end.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// do some long running processing here
// Check that there was not a nil handler passed.
if( completionHandler1 )
{
completionHandler1();
}
});
});
Upvotes: 0
Reputation: 6982
What you want is easily achieved with Operation
instead of GCD. Operation
class has addDependency(_ op: Operation)
function. Put your code in BlockOperation
instances, add dependencies and run them in OperationQueue
Upvotes: -1