2017-06-15 59 views
0

在我的代碼我有多個位置,我必須檢查所有的位置是否正確(檢查與谷歌API)如果位置是正確的我必須得到該位置的座標。如何等待for循環(Xcode,Objective C,iOS)中的callBack方法(或)響應?

我想在for循環中編寫代碼是否有任何方法來等待for循環中的響應。

我在下面粘貼我的代碼。

在此先感謝。

for (int locationsCount=0;locationsCount<results.count;locationsCount++) 
    { 
     NSString *googlelocations = [[results objectAtIndex:locationsCount]objectForKey:@"description"]; 

     if ([locationAddress isEqualToString:googlelocations]) 
     { 
      [[LocationManager share] fetchLatLngForPlacename:googlelocations placeId:[[results objectAtIndex:locationsCount] objectForKey:@"place_id"] completion:^(double lat, double lng, NSError *error) 
      { 
       [SVProgressHUD dismiss]; 

       if (error) { 

       }else { 

        CLLocation *locationCoordinates = [[CLLocation alloc]initWithLatitude:lat longitude:lng]; 

        NSMutableArray *globalArray = [[LocationManager share]getManualInterLocationArray]; 
        NSMutableDictionary *dict = [[globalArray objectAtIndex:selectedTextField.tag] mutableCopy]; 

        [dict setObject:locationCoordinates forKey:@"location_coordinates"]; 

        [dict setObject:googlelocations forKey:@"location_Address"]; 

        [dict setObject:[NSNumber numberWithBool:true] forKey:@"manualEntry_Flag"]; 

        [globalArray replaceObjectAtIndex:selectedTextField.tag withObject:dict]; 

        [[LocationManager share]saveManualInterLocationArray:globalArray]; 

       } 

      }]; 
     } 
    } 

回答

0

我對此要求使用遞歸方法它現在工作正常。遞歸方法是實現這一要求的最佳和簡單的方法。

-(void)addressValidation:(int)locationCount andCompletion:(void(^)(BOOL isSuccess))callBack{ 
if (manualarraycount >= globalArray.count) 
{ 
    callBack(true); 
    return; 
} 

[[LocationManager share] fetchOfflineAutoCompleteSuggestionForKey:locationAddress LocationCoordinates:location Radius:duration completion:^(NSArray *results, NSError *error){ 
    // --------- do what you want ------------ 
    [self addressValidation:manualarraycount+1 andCompletion:callBack]; 
}]; 

}

0

嘗試使用遞歸。創建一個函數

-(void)setLocation:(NSUInteger)locationCount andCompletion:(void (^))completionBlock{ 
    if (locationsCount>=results.count) { 
     if (completion) { 
       completion(); 
     } 
     return; 
    } 
    NSString *googlelocations = [[results objectAtIndex:locationsCount]objectForKey:@"description"]; 

    if ([locationAddress isEqualToString:googlelocations]) 
    { 
     [[LocationManager share] fetchLatLngForPlacename:googlelocations placeId:[[results objectAtIndex:locationsCount] objectForKey:@"place_id"] completion:^(double lat, double lng, NSError *error) 
     { 
      [SVProgressHUD dismiss]; 

      if (error) { 

      }else { 

       CLLocation *locationCoordinates = [[CLLocation alloc]initWithLatitude:lat longitude:lng]; 

       NSMutableArray *globalArray = [[LocationManager share]getManualInterLocationArray]; 
       NSMutableDictionary *dict = [[globalArray objectAtIndex:selectedTextField.tag] mutableCopy]; 

       [dict setObject:locationCoordinates forKey:@"location_coordinates"]; 

       [dict setObject:googlelocations forKey:@"location_Address"]; 

       [dict setObject:[NSNumber numberWithBool:true] forKey:@"manualEntry_Flag"]; 

       [globalArray replaceObjectAtIndex:selectedTextField.tag withObject:dict]; 

       [[LocationManager share]saveManualInterLocationArray:globalArray]; 

      } 

     }]; 
    } 
} 

在你完成塊調用函數本身與增量次數:

[self setLocation:locationCount++ andCompletion:nil]; 

,並開始你的重複調用,你需要從0

[self setLocation:0 andCompletion:^{ 
// handle completion 
}]; 
+0

我想要的方式進行回調。可能嗎? –

+0

是的! A編輯了答案 – iamirzhan

+0

上述方法被回調函數調用,所以完成該過程後我們必須發送確認才能繼續下一個過程。如果(appDelegate()。internetSatus == false){ return;}(void)(void } addressArrayCount = 0; (自動地址驗證:地址數組和計數完成:^(BOOL isSuccess) { if(isSuccess){callBack(true); NSLog(@「completed」); } }]; } –

0

啓動功能可以使用調度組,如在此僞代碼中:

dispatch_group_t loadDetailsGroup=dispatch_group_create(); 

for(id thing in thingsToDo) 
{ 
    dispatch_group_enter(loadDetailsGroup); 

    // call method with completion callback, and in the callback run 
    dispatch_group_leave(loadDetailsGroup); 
} 

// Now outside the loop wait until everything is done. NOTE: this will block! 
dispatch_group_wait(loadDetailsGroup, DISPATCH_TIME_FOREVER); 

如果您在主線程上運行此操作,則不應該阻止它,以便UI保持響應。所以,你可以在後臺做等待部分,完成後則可能做一些在主線程:

// to background 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{ 
    // wait in background 
    dispatch_group_wait(loadDetailsGroup, DISPATCH_TIME_FOREVER); 

    // back to main (not needed if what you need to do may happen in background) 
    dispatch_async(dispatch_get_main_queue(),^{ 

     // do stuff here that affects the UI 
    }); 
}); 

編輯:庫爾特雷維斯指出,如果要異步等待,有所回調, dispatch_group_notify()更適合這一點。所以整個上面的代碼可以被壓縮到:

dispatch_group_t loadDetailsGroup=dispatch_group_create(); 

for(id thing in thingsToDo) 
{ 
    dispatch_group_enter(loadDetailsGroup); 

    // call method with completion callback, and in the callback run 
    dispatch_group_leave(loadDetailsGroup); 
} 

// Now outside the loop wait until everything is done. NOTE: this will 
// not block execution, the provided block will be called 
// asynchronously at a later point. 
dispatch_group_notify(loadDetailsGroup,dispatch_get_main_queue(),^{ 

    // Callback 
}); 
+1

在你的第二個代碼塊中,執行'dispatch_group_notify(loadDetailsGroup,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^ {...});是不是更直接?這樣你可以避免讓隊伍坐在隊列中等待。 –

+0

好點Kurt,謝謝!我修改了我的例子。 –