【问题标题】:Concurrency iterating over NSArrayNSArray 上的并发迭代
【发布时间】:2016-08-06 07:50:23
【问题描述】:

我有一个array 的用户对象。我需要遍历这个数组,然后,对于每个用户,我需要根据其用户 ID 发出获取数据的请求。此请求是一个异步请求(由于我无法使其同步的原因)。这是使用 dispatch_group 调用编辑的代码:

已编辑

for (User *user in self.userList) {
    dispatch_group_enter(self.usersGroup);
    [self.wrapper getUserDataWithId:user.userid completion:^(Owner *owner, NSError *error) {
        user.owner = owner;
        dispatch_group_leave(self.usersGroup);
    }];
}

dispatch_group_notify(self.usersGroup, dispatch_get_main_queue(), ^{
   // All requests have finished
   // Stuff with updated userlist
});

主要问题很明显:当第一个请求完成时,它拥有的用户引用不是发起请求的那个,所以我没有正确的关联。

有什么简单而优雅的方法来解决这个问题吗?提前致谢!

【问题讨论】:

  • 该块将捕获user 的值,因此将在正确的对象上设置所有者。您如何等待所有请求完成?
  • 该块只知道一个 id(字符串),但不引用用户对象。我尝试使用 dispatch_group 等待所有请求完成,但返回的数组没有相关数据
  • 添加您尝试使用调度组的代码将帮助人们帮助您。

标签: ios objective-c concurrency queue


【解决方案1】:

正如@Paulw11 建议的那样,循环不会等待你执行块,所以我建议你使用这样的递归函数而不是 for 循环。

- (void)getOwnerForObectAtIndex:(NSInteger)index {
    if (index < self.userList) {
        User *user = [self.userList objectAtIndex:index];
        [self.wrapper getUserDataWithId:user.userid completion:^(Owner *owner, NSError *error) {
            user.owner = owner;
            [self getOwnerForObectAtIndex:index+1];
        }];
    }
    else {
        //Now all User have its corresponding owner, Handle array Now. 
    }
}

现在像这样调用这个函数[self getOwnerForObectAtIndex:0];

【讨论】:

  • 我尝试使用 dispatch_group 但也许递归函数是更好的解决方案。谢谢!!
  • OPs 循环将在为每个元素启动异步任务后完成,您的递归解决方案将在为第一个元素启动异步任务后返回,两者都不会等待所有任务完成OP 希望。
  • @CRD 不,这会起作用,因为我在他正确得到响应检查后再次调用我的函数。块语句只有在他得到响应时才执行。
  • OP 需要在所有异步任务完成后处理数组。你的代码是如何做到这一点的?
  • @CRD 检查编辑,它只需要添加一个 else 块。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-02
  • 1970-01-01
  • 2021-11-19
  • 2013-12-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多