2014-08-31 2 views
0

У меня есть for/in петлю следующим образом:только продолжать цикл, если метод закончил

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

Метод getPaymentDetails является асинхронным. Как создать блок завершения, чтобы продолжить цикл for/in, если метод закончен?

  • детали

Метод 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 *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); 
           } 
          }]; 

} 

Определение «законченный» Настоящим определяется, когда сумма, а также валюта хранилась в массиве , Или, другими словами: когда кодовый блок достиг конца метода для этого конкретного paymentId

+0

Метод getPaymentDetails изменяет некоторую переменную? В этом случае вы можете поместить время (myVar == nil) {// empty}^{YourBlockHere} myVar = nil – Draelach

+1

@iZabala Тесная петля петли в любом потоке - плохая идея. Это особенно плохо на основной теме – Paulw11

+0

Нет общего определения того, когда асинхронный метод «завершен». Это полностью зависит от того, что делает этот метод, и того, что вы хотели бы «заполнить». При отсутствии каких-либо подробностей самым простым ответом является изменение синхронности 'getPaymentDetails' и перемещение этого цикла с основного потока. –

ответ

1

Вы можете использовать семафоры для такого рода синхронизации. Семафоры являются базовым строительным блоком в параллелизме и, среди прочего, ожидают ожидание. GCD предоставляет семафоры через dispatch_semaphore-create, dispatch_semaphore_signal и dispatch_semaphore_wait.

В самых общих чертах сначала создать семафор:

dispatch_semaphore_t sema = dispatch_semaphore_create(0); 

то в вашей засаде петли на этом семафор:

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

, а затем в соответствующем месте на вашем фоне завершения сигнала блока с:

dispatch_semaphore_signal(sema); 

Для получения дополнительной информации о API см. Руководство ()), для семафоров найти книгу (или интернет).

HTH

+0

Спасибо! Кажется, это уже много работает. Я не очень разбираюсь в этой теме, поэтому я прочитаю ее. Тем не менее, моя облачная функция, кажется, берет навсегда сейчас, и блок внутри нее никогда не называется. Знаете ли вы, что это за причины? – bdv

Смежные вопросы