Wait until all iOS blocks are executed before moving on

假装没事ソ 提交于 2020-01-22 01:48:25

问题


I have a data model/store object that interfaces with the Internet over several APIs containing data. The number of APIs to be interfaced with is dynamic: from a conceptual standpoint, we can consider the endpoints to be strings in an NSMutableArray. The issue is that I want to notify views/other observers of updated data after the last endpoint/API call is completed. I tried GCD dispatch but the following pattern doesn't seem to work properly:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();

dispatch_group_async(group, queue, ^{

    for(MyAPIEndpoint __weak __block *ep in apiList)
    {

       [self runAPI:ep withCompletionBlock:^(MyAPIEndpoint *api, NSError *err)
       {
           // update the data model here, code omitted as it's not relevant
       }
       ];
    }
});

dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

// this statement must only execute AFTER the last block in the for loop above is done
[[NSNotificationCenter defaultCenter] postNotificationName:@"apiDataUpdated" object:self];

However, it doesn't seem to work; it seems the code inside that [self runAPI...] call is never executed at all?


回答1:


I played around with dispatch groups the other day, here is a really helpful blog post by jrturton which should help you with the basics!

But basically it looks like your missing the line to enter/leave the dispatch group. So non of your runAPI methods are being run as you have no items in the group and [[NSNotificationCenter defaultCenter] postNotificationName:@"apiDataUpdated" object:self]; gets called straight away.

dispatch_group_t group = dispatch_group_create();

for(MyAPIEndpoint __weak __block *ep in apiList)
{
    dispatch_group_enter(group);
    [self runAPI:ep withCompletionBlock:^(MyAPIEndpoint *api, NSError *err)
    {
        // update the data model here, code omitted as it's not relevant
        dispatch_group_leave(group);
    }];
}
});

dispatch_group_notify(group, dispatch_get_main_queue(),^{
    [[NSNotificationCenter defaultCenter] postNotificationName:@"apiDataUpdated" object:self];
});


来源:https://stackoverflow.com/questions/23034343/wait-until-all-ios-blocks-are-executed-before-moving-on

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!