我正在编写一个利用 UITabBarController 切换视图的应用程序。在填充 UITableView 之前,一个选项卡发出 Web 请求以收集并处理 JSON 数据。我正在尝试在后台加载此数据,因此当用户按下选项卡时,呈现表格不会延迟。将显示一个 ActivityIndicator,然后在表格中加载数据。
每个请求都被提出、处理并将结果放置在一个 NSMutableArray 中,然后对其进行排序并添加到 UITableView。
当我使用 dispatch_sync 时,数据被加载并且数组被创建并呈现得很好,但是视图的 UI 被阻止加载。我在想,因为出于某种原因,我没有将此查询发送到后台队列。如果我使用 dispatch_async,当尝试访问主线程上的 NSMutableArray 时会出现异常。
所以,我的问题是什么是允许用户切换到包含此 TableView 的选项卡的正确模式,在数据加载和处理(在后台)时呈现一个 ActivityIndicator,然后一旦完成,UITableView 就会加载处理过的数据。
来自 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];
}