如何在上一次第一次dispatch_async完成后执行第二次dispatch_async?

时间:2017-07-13 09:18:17

标签: ios objective-c grand-central-dispatch nsoperationqueue dispatch-async

我想顺序添加一个dispatch_async,但我希望它们不会随机启动。 我想举个例子:

dispatch_async 1开始......
dispatch_async 1结束。

dispatch_async 2开始......
dispatch_async 2结束。

dispatch_async 3开始......
dispatch_async 3结束。

我需要更新一个sqlite,并且第一次调度中的信息对于第二次调度是必要的......

-(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];
                                 });

            }
        }
...

提前致谢。

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];
                    });
                });

6 个答案:

答案 0 :(得分:3)

定义您自己的串行队列

并添加这样的代码

 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 */ });

串行队列保证任务将按照提交的顺序并以串行方式(一次一个)进行修改

答案 1 :(得分:2)

要从字面上理解你的Q,你必须嵌套电话:

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

  }

}

但您应该考虑使用自定义序列队列或NSOperation等等。

使用序列号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
}); 

答案 2 :(得分:1)

您可以将所有dispatch_async作为串行队列并逐个执行

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");
});

答案 3 :(得分:0)

最好的方法是使用NSOperations&将它们添加到queue.so它将按完成顺序调用

但如果你想以同样的方式做到这一点,那么定义完成块&添加你的dispatch_async2&完成块中的dispatch_Async3&最后调用那些完成块。

    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();
            }
            });
        });

答案 4 :(得分:0)

添加此类代码
您也可以设置PRIORITY。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

});

});

答案 5 :(得分:-1)

使用Operation代替GCD可轻松实现您的目标。 Operation类具有addDependency(_ op: Operation)函数。将代码放在BlockOperation个实例中,添加依赖项并在OperationQueue

中运行它们