10我在SOF上关注了使用GCD进行异步调用的几篇文章,如果远程服务器响应速度够快,就像在本地测试服务器上工作和测试时一样正常工作。主线程不等待异步强制
SOF解决方案尝试:
Waiting until two async blocks are executed before starting another block
iPhone - Grand Central Dispatch main thread
现在,我有一个远程服务器建立其采取至少8秒钟返回它的JSON数据和GCD代码充当如果它没有等待异步调用在更新UI之前完成,我最终得到了一个空的表视图。
我能得到这个正确的行为的唯一方法是通过在该行
[NSThread sleepForTimeInterval:10.0];
迫使应用程序等待10秒,允许离开“[自我runUnirestRequest:requestUrl]。”返回数据,然后我得到数据。这显然是一个黑客,并希望让我的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];
}
}
看看这个问题http://stackoverflow.com/questions/11909629/waiting-until-two-async-blocks-are-executed-before-starting-another-block – tkanzakic
感谢您的回复,我确实尝试过,并且完全一样。除去sleepForTimeInterval调用还会添加错误“嵌套的推动动画可能导致损坏的导航栏”,另外两个涉及“”调用。是否有dispatch_async的onComplete块?不能发现这样的事情。 –
'runUnirestRequest'中有什么?对于'onComplete',你应该使用一个操作队列,而不是GDC队列。 – Wain