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

koe*_*oen 0 core-data grand-central-dispatch ios

我正在努力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];
}
Run Code Online (Sandbox Code Playgroud)

我在日志中看到的是

enter
leave
enter
leave
...
save
end import
...
Run Code Online (Sandbox Code Playgroud)

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

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

Mik*_*e S 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);
                          }
    }];

}
Run Code Online (Sandbox Code Playgroud)

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