Objective c 在UITabViewController中使用dispatch_sync检索数据
我正在编写一个应用程序,它利用UITabBarController切换视图。一个选项卡在填充UITableView之前发出web请求以收集并处理JSON数据。我试图在后台加载这些数据,这样当用户按下选项卡时,就不会延迟显示表格。将显示一个ActivityIndicator,然后该表将加载数据 每个请求都会发出、处理并将结果放入NSMutableArray中,然后将其排序并添加到UITableView中 当我使用dispatch_sync时,数据被加载,数组被创建并显示良好,但是视图的UI被阻止加载。我这样想是因为出于某种原因,我没有将此查询发送到后台队列。如果使用dispatch_async,则在尝试访问主线程上的NSMutableArray时会出现异常 因此,我的问题是,允许用户切换到包含此TableView的选项卡,在加载和处理数据(在后台)时显示ActivityIndicator,然后在完成后,使用处理后的数据加载UITableView的正确模式是什么 UITableViewController中的相关代码:Objective c 在UITabViewController中使用dispatch_sync检索数据,objective-c,xcode,uitableview,grand-central-dispatch,uitabview,Objective C,Xcode,Uitableview,Grand Central Dispatch,Uitabview,我正在编写一个应用程序,它利用UITabBarController切换视图。一个选项卡在填充UITableView之前发出web请求以收集并处理JSON数据。我试图在后台加载这些数据,这样当用户按下选项卡时,就不会延迟显示表格。将显示一个ActivityIndicator,然后该表将加载数据 每个请求都会发出、处理并将结果放入NSMutableArray中,然后将其排序并添加到UITableView中 当我使用dispatch_sync时,数据被加载,数组被创建并显示良好,但是视图的UI被阻止加
#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];
}
Dispatch\u sync()
实际上会阻止从中调用它的线程,因为它会停止执行以使块排队Dispatch\u async
是一个更好的选择,因为它允许继续调用函数。您可以将一个调用封装在另一个调用中,以允许您在主线程上执行完成代码。这也使得代码的执行非常容易阅读
// Turn on status bar spinner, for example
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// Do background stuff here
....
NSData* data = [NSData dataWithContentsOfURL:myURL];
// used parsed data to populate data structure of some type
....
dispatch_async(dispatch_get_main_queue(), ^{
// Use background stuff here
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
});
});
虽然像
NSURLConnection
这样的基于回调的API可能最适合网络加载,但这将非常有效。特别是对于小请求。谢谢!我相信我在后台可以很好地工作,但是随后的代码访问NSMutableArray,并在加载数据之前访问它,从而导致异常。在访问数据之前,我应该如何等待以确保数据已加载和排序?在“在此处使用背景资料”部分之前,您不应该使用加载的数据。这可能会复制您获取的数据并调用reloadTable