Я пишу приложение, которое использует UITabBarController для переключения представлений. Одна вкладка выполняет веб-запрос для сбора и обработки данных JSON перед заполнением UITableView. Я пытаюсь загрузить эти данные в фоновом режиме, поэтому, когда пользователь нажимает на вкладку, нет задержки в представлении таблицы. ActivityIndicator будет отображаться, а затем таблица загружается с данными.
Каждый запрос выполняется, обрабатывается и результаты помещаются в NSMutableArray, который затем сортируется и добавляется в UITableView.
Когда я использую dispatch_sync, данные загружаются, и массив создается и отображается нормально, однако пользовательский интерфейс для представления заблокирован от загрузки. Я думаю, потому что по какой-то причине я не получаю этот запрос в фоновую очередь. Если я использую dispatch_async, я получаю исключения, когда делаю попытку доступа к NSMutableArray в основном потоке.
Итак, мой вопрос в том, что является правильным шаблоном, позволяющим пользователю переключиться на вкладку, которая содержит этот TableView, представить ActivityIndicator, пока данные загружаются и обрабатываются (в фоновом режиме), а затем после завершения UITableView загружается с обработанными данными.
Relavent код из UITableViewController:
#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
- (void)viewDidLoad
{
[super viewDidLoad];
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
currentLat = appDelegate.currentLatitude;
currentLong = appDelegate.currentLongitude;
finalDistanceArray = [[NSMutableArray alloc] init];
[self compareLocationMMC];
[self compareLocationLVMC];
[self compareLocationSBCH];
[self compareLocationGVCH];
[self compareLocationSYVCH];
NSSortDescriptor *lowestToHighest = [NSSortDescriptor sortDescriptorWithKey:@"distance" ascending:YES];
[hospitalList sortUsingDescriptors:[NSArray arrayWithObject:lowestToHighest]];
}
- (void)compareLocationMMC {
NSString * searchURL = [NSString stringWithFormat:@"http://maps.googleapis.com/maps/api/directions/json?origin=%f,%f&destination=%f,%f&sensor=true", currentLat.floatValue, currentLong.floatValue, MMC_LAT, MMC_LON];
NSURL * myURL = [NSURL URLWithString:searchURL];
dispatch_sync(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL:
myURL];
[self performSelectorOnMainThread:@selector(fetchedData:)
withObject:data waitUntilDone:YES];
});
}
//The compareLocationXXX method is repeated 4 more times with different search strings
- (void)fetchedData:(NSData *)responseData {
//parse out the json data
NSError* error;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:responseData
options:kNilOptions
error:&error];
NSArray* stationDistance = [json objectForKey:@"routes"];
NSDictionary* legs = [stationDistance objectAtIndex:0];
NSArray* legsBetween = [legs objectForKey:@"legs"];
NSDictionary* distanceBetween = [legsBetween objectAtIndex:0];
finalDistance = [distanceBetween valueForKeyPath:@"distance.text"];
[finalDistanceArray addObject:finalDistance];
}