only continue loop if method has finished

被刻印的时光 ゝ 提交于 2019-12-25 06:04:11

问题


I have a for/in loop like so:

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

The method getPaymentDetails is asynchronous. How do I create a completion block to only continue the for/in loop if the method has finished?

  • details

the method getPaymentDetails looks like this:

-(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 *currency = [payment objectForKey:@"currency"];
                                  if (![currency isKindOfClass:[NSNull class]]) {
                                    [self.currencyArray addObject:currency];
                                  }
                                  else {
                                    [self.currencyArray addObject:@""];
                                  }

                                  [self.tableView reloadData];

                                } else{

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

}

The definition of "finished" is hereby defined when the amount as well as the currency has been stored in the array. Or in other words: when the code block has reached the end of the method for that specific paymentId


回答1:


You can use semaphores for this kind of synchronisation. Semaphores are a basic building block in concurrency and provide among other things non-busy waiting. GCD provides semaphores through dispatch_semaphore-create, dispatch_semaphore_signal and dispatch_semaphore_wait.

In very general outline first create a semaphore:

dispatch_semaphore_t sema = dispatch_semaphore_create(0);

then in your loop wait on this semaphore:

for(NSString *paymentId in success)
{
   [self getPaymentDetails:paymentId];
   dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); // wait for call to signal completion
}

and then at the appropriate place in your background block signal completion with:

dispatch_semaphore_signal(sema);

For more details on the API see the manual (man command), for semaphores find a book (or the internet).

HTH



来源:https://stackoverflow.com/questions/25597081/only-continue-loop-if-method-has-finished

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!