信号量:没有看到我的回调方法被调用,死锁

Jas*_*ues 5 semaphore objective-c grand-central-dispatch ios

我有两个轻量级的网络请求,我想同时执行,然后当两者都完成时,调用一个块函数.

我创建了如下方法:

- (void)loadWithCompletion:(void (^)())completion
{
    dispatch_semaphore_t customerSemaphore = dispatch_semaphore_create(0);
    dispatch_semaphore_t communitySemaphore = dispatch_semaphore_create(0);

    dispatch_async(dispatch_queue_create("mp.session.loader", DISPATCH_QUEUE_CONCURRENT), ^(void)
    {
        [_customerClient loadCustomerDetailsWithSuccess:^(MPCustomer* customer)
        {
            [self setCurrentCustomer:customer];
            dispatch_semaphore_signal(customerSemaphore);
        } error:^(NSError* error)
        {
            LogDebug(@"Got unexpected error loading customer details: %@", error);
        }];

        [_customerClient loadCommunityDetailsWithSuccess:^(MPCommunity* community)
        {
            [self setCurrentCommunity:community];
            dispatch_semaphore_signal(communitySemaphore);
        } error:^(NSError* error)
        {
            LogDebug(@"Got unexpected error loading customer details: %@", error);
        }];
    });

    dispatch_semaphore_wait(customerSemaphore, DISPATCH_TIME_FOREVER);
    dispatch_semaphore_wait(communitySemaphore, DISPATCH_TIME_FOREVER);

    if (completion)
    {
        completion();
    }
}
Run Code Online (Sandbox Code Playgroud)

..它最终会永远等待.我看到我的两个网络请求启动,但我从来没有调用两个客户端调用的两个回调,因此两个信号量都没有发出信号.

为什么?

小智 1

我想知道您创建的调度队列是否在运行该块之前被销毁。但是为并发操作创建调度队列是没有意义的。相反,这样做:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void)...
Run Code Online (Sandbox Code Playgroud)

更新:

另外,您是否检查过您的网络库没有在主队列上回调?这会导致僵局。