在后台解析调用函数会扰乱顺序

时间:2014-08-31 19:51:38

标签: ios objective-c multithreading parse-platform objective-c-blocks

我需要检索与id进行比较的几个NSDicionaries

首先,我打电话给NSArray,其中包含这些ID。我循环遍历它们以查看获取该ID的详细信息,并且我将调用另一个pfcloud函数。到目前为止,一切顺利。但是,当我记录付款ID的付款详细信息时,订单序列的顺序与我输入的数组的顺序不同。

for(__block NSString *paymentId in success){
   [self getPaymentDetails:paymentId];
}

例如:success = @[@"1",@"2",@"3"]

方法getPaymentDetails会记录我@[@"details about 1", @"details about 3", @"details about 2"]

但是,我需要它们的顺序完全相同。 这是我的getPaymentDetails代码:

-(void)getPaymentDetails:(NSString *)paymentId{
PFUser *currentUser = [PFUser currentUser];
  [PFCloud callFunctionInBackground:@"getpaymentdetails"
                     withParameters:@{@"objectid": paymentId, @"userid": currentUser.objectId}
                              block:^(NSDictionary *success, NSError *error) {
                                if(success){
                              NSDictionary *payment = success;
                              NSString *amount = [payment objectForKey:@"amount"];
                              if (![amount isKindOfClass:[NSNull class]]) {
                                [self.amountArray addObject:amount];
                              }
                              else {
                                [self.amountArray addObject:@""];
                              }

                              NSString *from = [payment objectForKey:@"from"];
                              if (![from isKindOfClass:[NSNull class]]) {
                                [self.fromArray addObject:from];
                              }
                              else {
                                [self.fromArray addObject:@""];
                              }

                            } else{
                              NSLog(@"Error logged getpaymentdetails: %@", error);
                            }

                          }]; 
}

例如,amountArray中存储的值与paymentId的索引不匹配 怎么解决这个问题?

2 个答案:

答案 0 :(得分:0)

请求callFunctionInBackground将以异步方式执行,并且无法保证您在循环中进行的第一次调用将首先完成。这与Parse本身并不完全相关,这就是如何完成它的本质。每次执行此代码时,您可能会巧合地使用相同的顺序或完全随机的顺序。

如果您希望订单保持不变,请将所有ID传递到您的Cloud功能并更新您的Cloud功能以处理它,或者始终等待一个调用完成,将结果添加到您的阵列然后获取详细信息使用下一个ID(基本上是一个队列)。

答案 1 :(得分:0)

将整个for循环移动到后台然后同步调用Parse函数可能更简单

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, ^{

    for(__block NSString *paymentId in success){
       [self getPaymentDetails:paymentId];
    }

});

dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

// Release the group when it is no longer needed.
dispatch_release(group);

然后在您的getPaymentDetails中,您可以致电callFunction:withParameters:error:而不是callFunctionInBackground:withParameters:

然而,这并不是一个理想的解决方案,因为您要消除并发性,因此执行时间会更长。

更好的解决方案是处理这样一个事实,即在循环结束时数组是无序的,并在检索完所有数据后对其进行排序