iphone - dispatch_group_wait 与 GCD

标签 iphone ios multithreading concurrency grand-central-dispatch

因此,我将一组图像发布到我的服务器。我想使用 GCD 异步发布数组,但我也想使发生这种情况的方法同步,以便我可以传回单个响应对象。然而,方法 dispatch_group_wait 似乎立即返回(而不是等待我的 block 完成)。这是一个问题,因为我在一个 block 中使用一个 block 吗?

NSArray *keys = [images allKeys];
__block NSMutableDictionary *responses = [NSMutableDictionary dictionaryWithCapacity:[images count]];

dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
for (int i = 0; i < [keys count]; i++) {
    __block NSString *key = [keys objectAtIndex:i];
    dispatch_group_async(group, queue, ^{
        [self postImage:[images objectForKey:key] completionHandler:^(ServerResponse *response){
            @synchronized(responses){
                if ([response succeeded]) {
                    NSString *value = [[response data] objectForKey:@"image_token"];
                    [responses setObject:value forKey:key];
                    NSLog(@"inside success %@",responses);
                } else {
                    NSString *error = response.displayableError;
                    if (!error) {
                        error = @"Sorry something went wrong, please try again later.";
                    }
                    [responses setObject:error forKey:@"error"];
                    [responses setObject:response forKey:@"response"];
                }
            }
        }];
    });
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
dispatch_release(group);

我只想等待所有 [self postImage] 方法从服务器回调并修改响应字典。

最佳答案

Jonathan 的信号量示例是正确的。但是,我提到使用条件变量作为替代方案,所以我想我至少会发布一个示例。一般来说,一个 CV 可以用来等待更一般的条件,而不仅仅是 N 个 worker 。

请注意,条件变量有它们的位置(虽然不一定在这里),通常最好是当已经需要锁来改变共享状态时,其他线程可以等待特定条件。

NSUInteger numKeys = [keys count];

NSConditionLock *conditionLock = [[NSConditionLock alloc] initWithCondition:numKeys];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
for (NSUInteger i = 0; i < numKeys; i++) {
    __block NSString *key = [keys objectAtIndex:i];
    dispatch_async(queue, ^{
        [self postImage:[images objectForKey:key] completionHandler:^(ServerResponse *response){
            // Basically, nothing more than a obtaining a lock
            // Use this as your synchronization primitive to serialize access
            // to the condition variable and also can double as primitive to replace
            // @synchronize -- if you feel that is still necessary
            [conditionLock lock];

            ...;

            // When unlocking, decrement the condition counter
            [conditionLock unlockWithCondition:[conditionLock condition]-1];
        }];
    });
}

// This call will get the lock when the condition variable is equal to 0
[conditionLock lockWhenCondition:0];
// You have mutex access to the shared stuff... but you are the only one
// running, so can just immediately release...
[conditionLock unlock];

关于iphone - dispatch_group_wait 与 GCD,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12030092/

相关文章:

iphone - 从 SQLITE 数据库中删除数据的 Objective-C 问题 - 结果代码 5

iphone - 图片放入数组 ios开发

iphone - 加载 ViewController 时显示事件指示器

ios - NSURLRequest 的默认 setHTTPMethod 是什么?是 "POST"还是 "GET"?

ruby-on-rails - Rails 中的多线程 : Circular dependency detected while autoloading constant

ios - Flex Mobile HTTPService 期间的 "Loading"图标

ios - 有没有办法识别该应用程序是通过 didFinishLaunchingWithOptions 中的 firebase 动态链接安装的?

ios - 如何快速返回多个值

java - 两个线程并发修改HashMap

java - 如何杀死应用程序中由第 3 方库设计的所有线程