在完成所有任务之前调用dispatch_group_notify

时间:2014-08-26 01:54:12

标签: ios core-data grand-central-dispatch

我在dispatch_groupdispatch_group_notify之间挣扎,在所有任务完成之前调用它。我试图做的是迭代一些查询,获取它们,并将返回的XML处理成CoreData实体。然后,当一切都完成后,我调用上下文保存所有数据到商店。但是在所有任务完成之前调用dispatch_group_notify,并且不保存任何内容。

以下是一些代码:

dispatch_group_t dispatchGroup = dispatch_group_create();

for (NSString *query in queryArray)
{
    dispatch_group_enter(dispatchGroup);
    NSLog(@"enter");

    [myDownloadClient searchForQuery: query
                      withParameters: nil
                          completion: ^(NSData *data, NSError *error) {
                             [self processXML: data];
                             NSLog(@"end import");
    }];

    NSLog(@"leave");
    dispatch_group_leave(dispatchGroup);
}

dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(),^{
    NSLog(@"save");
    [self saveContext];
}

我在日志中看到的是

enter
leave
enter
leave
...
save
end import
...

如您所见,在完成所有下载和XML处理之前会显示save,因此无需保存。

我怎样才能让它发挥作用?

2 个答案:

答案 0 :(得分:6)

看起来[myDownloadClient searchForQuery:query ...]是一种异步方法。在致电dispatch_group_leave后致电[myDownloadClient searchForQuery:query ...]并没有真正做任何事情;你基本上是进入小组,然后立即离开。相反,您需要在dispatch_group_leave完成块[self processXML:data]之后调用searchForQuery:...

for (NSString *query in queryArray)
{
    dispatch_group_enter(dispatchGroup);
    NSLog(@"enter");

    [myDownloadClient searchForQuery: query
                      withParameters: nil
                          completion: ^(NSData *data, NSError *error) {
                              [self processXML: data];
                              NSLog(@"end import");

                              NSLog(@"leave");
                              dispatch_group_leave(dispatchGroup);
                          }
    }];

}

这样,在搜索和处理完成之前,您不会离开该组。

答案 1 :(得分:1)

当您调用for循环时,它不会处理其底部代码。直到那时。然而,那些提取是在代码块中。那些块正在等待返回,而你继续在for循环后处理底部代码。由于保存处理起来要快一些,因此在完成提取块之前,它将继续成为第一个。