同步两个异步调用

Vic*_*ico 0 multithreading asynchronous objective-c ios

早上好,

我的应用程序启动时有两个异步调用:一个获取推送通知的设备令牌,另一个尝试将用户登录到Facebook.

如果我没有两个异步调用的结果,我不能继续申请过程.

目前,我正在做这样的事情:两个布尔didFBConnectdidDeviceTokenObtained.

我正在一个线程中运行(显然非常糟糕):

while(!(didFBConnect && didDeviceTokenObtained)){ 
}
myFunctionToContinue();
Run Code Online (Sandbox Code Playgroud)

你知道处理这种情况的正确方法是什么吗?

BR

vig*_*o24 5

对此的可能解决方案是创建GCD调度组.看下面的这个例子(简单的应用程序),在同一个方法中,您将不在主线程中进行异步调用,您将:1.获取全局队列2.创建调度组3.在全局队列中调度异步并且在组中两个作业(FB连接和推送通知令牌)4.添加一个调度组等待组中的作业完成5.等待后添加你的myFunctionToContinue()

所以你要做的就是将两个工作排队,然后将它们分组,然后等待完成.这比在等待两个作业完成时使线程处于循环中更有效.

"gcdGroup"未在主线程中调用但在专用串行队列中调用的原因是为了避免在组等待时阻塞主线程.

通常,如果您的并发作业是高度异步的并且提供了很大的灵活性,那么使用GCD组非常方便,因为您可以添加其他条件而不会影响代码(只需创建块并放入组中).此外,您还可以调度创建自己的组的块,从而创建复杂的组图.


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    dispatch_queue_t serial_queue = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL);
    dispatch_async(serial_queue, ^{
        [self gcdGroup];
    });

    NSLog(@"Main thread not blocked...");

    return YES;
}

- (void)gcdGroup {
    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, ^{
        NSLog(@"Start First job");
        sleep(5);
        NSLog(@"End First job");
    });

    dispatch_group_async(group, queue, ^{
        NSLog(@"Start second job");
        sleep(arc4random()%5);
        NSLog(@"End second job");
    });

    NSLog(@"Now waiting for group to finish...");

    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

    NSLog(@"End of group");

}
Run Code Online (Sandbox Code Playgroud)

  • 是的,这是一个比我认为的公认解决方案更合适的解决方案. (2认同)