iOS:RestKit操作阻止在我想要的时候不执行

时间:2013-09-05 08:34:49

标签: ios ipad grand-central-dispatch restkit-0.20

我使用RestKit .20来映射两个对象。第二个对象取决于第一个。所以第一次操作必须在第二次操作之前进行。操作完成后,控制器使用模型对象在表视图中显示适当的信息。

第一个对象具有唯一的id,用于形成url请求的一部分以获取附加到它的对象。它的所有工作和请求正在获取信息并正确执行映射,但操作的操作完全错误,我只是无法理解它!

这就是我想要发生的事情:

  1. 查看加载并开始加载/映射第一个对象。
  2. 加载第一个对象后,第二个对象将被加载/映射。
  3. 表视图重新加载。
  4. 接下来会发生什么:

    1. 查看加载,加载表格视图。
    2. 操作最后执行,每次执行一个块操作,然后重新加载数据 - 不是我想要的解决方案,而是我能让它工作的唯一方法。
    3. 我很难解释所以有些代码:(我省略了不相关的代码)

      - (void)viewDidLoad
      {
          [super viewDidLoad]; 
          [self loadFirstObjects];        
          //omitted code
      
      }
      
      
      
      - (void)loadFirstObjects {
          //omitted code
      
          [operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
              self.pubRepos = mappingResult.array;
              [self loadSecondaryObjects];
          } failure:^(RKObjectRequestOperation *operation, NSError *error) {
              NSLog(@"ERROR: %@", error);
          }];
      
          [operation start];
      }
      
      - (void)loadSecondObjects
      {
          for (FirstObject *firstObject in firstObjects) {
      
              //Omitted code
      
              [operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
                  SecondObject *secondObject = [mappingResult.array objectAtIndex:0];
      
                  [secondObjects setObject:secondObject forKey:secondObject.idNum];
                  [table reloadData];
              } failure:^(RKObjectRequestOperation *operation, NSError *error) {
                  NSLog(@"ERROR: %@", error);
              }];
      
              [operation start];
      
          }
      }
      

      那么我该如何以我想要的方式工作呢?我希望能够先执行请求/映射,然后将所有信息加载到表中并更新它。我需要不断地从Web服务重新加载/映射新数据,以便与重新加载表分开。

      换句话说,最重要的问题是:如何准确控制操作块何时执行?

1 个答案:

答案 0 :(得分:1)

使用dispatch_group的方法很容易。您的-loadSecondObjects方法可能如下所示:

- (void)loadSecondObjects
{
    dispatch_group_t group = dispatch_group_create();

    for (FirstObject *firstObject in firstObjects) {
        // Omitted code
        dispatch_group_enter(group);
        [operation setCompletionBlockWithSuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
            SecondObject *secondObject = [mappingResult.array objectAtIndex:0];
            [secondObjects setObject:secondObject forKey:secondObject.idNum];
            dispatch_group_leave(group);
        } failure:^(RKObjectRequestOperation *operation, NSError *error) {
            NSLog(@"ERROR: %@", error);
            dispatch_group_leave(group);
        }];

        [operation start];
    }

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        [table reloadData];
    });
}

从本质上讲,这里发生的是你使用dispatch_group作为一个方便的计数器,增加了一个功能,你可以设置一个块,当计数器下一次击中零时执行。计数器从0开始。对于你开始的每个第二个对象加载,你递增计数器(通过调用dispatch_group_enter),然后对于完成(或失败)的每个第二个对象加载,你递减计数器(通过调用dispatch_group_leave)。当计数器达到0时,将执行使用dispatch_group_notify设置的块(此时您可以知道所有第二个对象加载操作都已完成。)

PS:因为我在你的代码中没有看到任何保留/释放调用,所以我假设你正在使用ARC。如果你不是,那么你需要dispatch_release小组。