一个接一个地运行3个方法

时间:2015-02-10 11:05:09

标签: objective-c xcode grand-central-dispatch nsurlsessiondatatask

我需要在一个调用api(NS​​URLSessionDataTask async)的单独线程中一个接一个地运行3个方法。我已经查看了调度组,但这似乎同时运行方法1和2,然后在完成时运行方法3:

dispatch_group_t group = dispatch_group_create();

//METHOD 1
dispatch_group_enter(group);
[self method1WithCompletion:^(BOOL success){
    dispatch_group_leave(group);
}];

//METHOD 2
dispatch_group_enter(group);
[self method2WithCompletion:^(BOOL success){
    dispatch_group_leave(group);
}];

dispatch_group_notify(group,dispatch_get_main_queue(),^{
    //METHOD 3
});

我需要它来运行方法1,当完成运行方法2时,当完成时最后运行方法3(排队方法)。

我知道我可以在每次完成时链接方法以运行下一个但我认为会有更好的方法来解决这个问题吗?

2 个答案:

答案 0 :(得分:0)

你很亲密。

dispatch_group_enter并且公司只处理使其成为一致的位,以便dispatch_group_enter进入dispatch_group_t的所有内容都将在调用传递到dispatch_group_notify的块之前完成。

因此我们可以在等待任务时充分利用它们。我们可以为每个需要完成的异步任务使用一个组,而不是只有一个组等待完成每个任务:

// You can get a global queue or create your own, it doesn't really matter
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// Create a group for each task you want to wait for
dispatch_group_t group1 = dispatch_group_create();
dispatch_group_t group2 = dispatch_group_create();

// Call your first task on the first group
dispatch_group_enter(group1);
[self method1WithCompletion:^(BOOL success){
    // Task is completed, so signal that it has finished
    dispatch_group_leave(group1);
}];

// Call your 2nd task on the 2nd group
dispatch_group_enter(group2);
// Make the second task wait until group1 has completed before running
dispatch_group_notify(group1, queue, ^{
    // METHOD 2
    [self method2WithCompletion:^(BOOL success){
        // Signal to the group that the task has completed
        dispatch_group_leave(group2);
    }];
});

// Nothing is waiting on the 3rd task, so no need to create a group for it
dispatch_group_notify(group2,dispatch_get_main_queue(),^{
    //METHOD 3
    // Do whatever you need to do in here
});

以下是有关Dispatch Queues以及如何使用它们的更多信息。

编辑:对不起,我完全改变了我的回答。一旦你离开你的评论,就会发现你所调用的任务是异步的,并且使用序列dispatch_queue_t不会产生任何影响! (这些块是串行运行的,但method2将在method1之后立即运行,而不是等待完成)

答案 1 :(得分:0)

已编辑: 我不再这么认为了, cjwirth 在评论中反驳了我的假设

我认为仍然可以采用serial queue(但这只是假设,我没有检查)。主要思想是将组的任务分配到串行队列,在分派之前使用dispatch_group_enter(group),在method1..2上使用dispatch_group_leave(group)完成。让我展示它应该是什么:

dispatch_queue_t queue = dispatch_queue_create("com.example.MyQueue", NULL);
dispatch_group_t group = dispatch_group_create();

//METHOD 1
dispatch_group_enter(group);
dispatch_group_async(group, queue, ^{
   [self method1WithCompletion:^(BOOL success){
   dispatch_async(queue, ^{                     
                     dispatch_group_leave(group);
             });
    }];
});

//METHOD 2
dispatch_group_enter(group);
dispatch_group_async(group, queue, ^{
   [self method2WithCompletion:^(BOOL success){
   dispatch_async(queue, ^{                     
                     dispatch_group_leave(group);
             });
    }];
});

dispatch_group_notify(group,dispatch_get_main_queue(),^{
    //METHOD 3
});

注意:这种实现看起来有些不对劲。因为我们已经有了NSOperationQueue,所以我建议你将NSURLSessionDataTask的东西包装成NSOperation并按顺序执行