10 我在 SOF 上关注了几篇关于使用 GCD 进行异步调用的帖子,如果远程服务器响应足够快,例如在本地测试服务器上工作和测试时,这可以正常工作。
尝试的 SOF 解决方案:
iPhone - Grand Central Dispatch 主线程
现在我已经设置了一个远程服务器,它至少需要 8 秒才能返回它的 JSON 数据,并且 GCD 代码的行为就像它在更新 UI 之前没有等待异步调用完成一样,我最终得到了一个表格视图那是空的。
我能让它正常运行的唯一方法是排队
[NSThread sleepForTimeInterval:10.0];
这会强制应用等待 10 秒并允许“[self runUnirestRequest:requestUrl];” 返回数据,然后我取回数据。这显然是一个 hack,并且想让我的 GCD 代码正常工作。
有没有办法让 UI 代码只在异步调用返回数据后执行?
注意:从 runUnirestRequest 返回的数据是 JSON 格式,并被反序列化并放入“salesData”的实例中。
我与 GCD 调用相关的代码如下:
- (void)viewDidLoad
{
...unrelated code...
[self createActivityIndicator];
dispatch_queue_t jsonQueue = dispatch_queue_create("com.ppos.pbsdashboard", NULL);
// Start block on background queue so the main thread is not frozen
// which prevents apps UI freeze
[activityIndicator startAnimating];
dispatch_async(jsonQueue, ^{
// Run remote RESTful request
[self runUnirestRequest:requestUrl];
// Force main thread to wait a bit to allow ansync dispatch
// to get its response with data
[NSThread sleepForTimeInterval:10.0];
// Everything in background thread is done.
// Call another block on main thread to do UI stuff
dispatch_sync(dispatch_get_main_queue(), ^{
// Back within main thread
[activityIndicator stopAnimating];
PBSVCDataDisplay *dataVc = [[PBSVCDataDisplay alloc] init];
[dataVc setSalesData:salesData];
[self performSegueWithIdentifier:@"showDataChart" sender:self];
});
});
}
runUnirestRequest 函数
- (void) runUnirestRequest:(NSString*)urlToSendRequestTo
{
[requestVCMessages setTextAlignment:NSTextAlignmentCenter];
[requestVCMessages setText:@"Processing request"];
// Handle errors if any occur and display a friendly user message.
@try{
NSDictionary* headers = @{@"p": settingsPassPhrase};
[[UNIRest get:^(UNISimpleRequest* request) {
[request setUrl:urlToSendRequestTo];
[request setHeaders:headers];
}] asJsonAsync:^(UNIHTTPJsonResponse* response, NSError *error) {
UNIJsonNode *jsonNde = [response body];
NSDictionary *jsonAsDictionary = jsonNde.JSONObject;
salesData = [self deserializeJsonPacket:(NSDictionary*)jsonAsDictionary withCalenderType:[requestParameters calendType]];
}];
}
@catch(NSException *exception){
[requestVCMessages setTextAlignment:NSTextAlignmentLeft];
NSString *errHeader = @"An error has occured.\n\n";
NSString *errName = [exception name];
NSString *errString = nil;
// Compare the error name so we can customize the outout error message
if([errName isEqualToString:@"NSInvalidArgumentException"]){
errString = [errHeader stringByAppendingString:@"The reason for the error is probably because data for an invalid date has been requested."];
}else{
errString = [errHeader stringByAppendingString:@"General exception. Please check that your server is responding or that you have requested data for a valid date."];
}
salesData = nil;
[requestVCMessages setText:errString];
}
}