考虑到以下代码,我将我的应用程序从同步调用移动到异步调用以停止UI冻结。 - 除了一些小细节外,一切正常。
当它是同步调用时,它们总是返回一个值(即使花了很长时间(5或6秒)) 但是现在:
ASync调用有时非常快,其他时间需要8或9秒(我也有光纤互联网)
他们提取的文本数据有时似乎没有返回,或者他们超时,因为myLabel文本最终设置为'NULL' - 我知道这不是我正在使用API的网站,因为它始终为Sync调用和浏览器返回一个值。
有什么想法吗? 谢谢!
编辑:日志的错误响应是:响应: 错误:(null)
[NSURLConnection sendAsynchronousRequest:requestGBP queue:operationQueue completionHandler: ^(NSURLResponse* response, NSData* data, NSError* error)
{
responseGBP = data;
NSString *json_stringGBP = [[NSString alloc] initWithData:responseGBP encoding:NSASCIIStringEncoding];
self.feedGBP = [parser objectWithString:json_stringGBP error:nil];
NSString *GBP = [NSString stringWithFormat:@"Info Last: %@" feedGBP ObjectForKey:@"value"]];
[myLabel setText:GBP];
}];
EDIIT ::我也在日志窗口看到“不应该到达这里”很多?!它不是我的NSLog代码的一部分!
答案 0 :(得分:1)
取决于您的队列,您如何以及在哪里推介operationQueue
?
更重要的是,何时调用异步连接?
如果你是在动画的UIView中调用它们,比如tableView或scrollView,那么当table / scrollView滚动时,队列将以这种方式运行。
为了能够调试更多信息,您还需要NSLog(@"Response: %@\r\nError: %@", response, error)
但是形成我的经验我非常怀疑第一种情况是造成这种情况,你也可以尝试使用默认队列而不是你自己的队列,这样的事情(不推荐,但可能有助于调试):
[NSURLConnection sendAsynchronousRequest:requestGBP queue:[NSOperationQueue currentQueue] completionHandler: ^(NSURLResponse* response, NSData* data, NSError* error)
编辑1:添加简单的代码更改以使事情变得更容易
正如我所怀疑的那样,你在动画视图中触发调用会导致延迟,我会做的是将aSync连接恢复为同步连接,而是在后台线程上调用它们。
以下是事物的外观(未经测试的代码,可能包含错误或需要进行一些调整)
将您的呼叫转移到新方法,称之为performRequest:(URLRequest *)req;
- (无效)performRequest:(的URLRequest *)aRequest {
NSError *err;
NSURLResponse *response;
NSData *returnData;
returnData = [NSURLConnection sendSynchronousRequest:aRequest
returningResponse:&response
error:&err];
if(!err && nil != returnData){
//Perform action with your data here
//IMPORTANT: if you have to use the data to update the UI again, then you
//Must perform that on the main thread, this code will always be called in the
//background thread, to do that simply do a call using GCD on the main Queue, like this
dispatch_async(dispatch_get_main_queue(), ^{
//Do only your UI updates here
});
}else{
NSLog(@"An error has occurred: %@", err);
}
}
无论何时您需要执行网络请求,(来自您的动画内等) 你只需在后台线程中调用它,就像这样
//Place this right after you create your requestGBP request
[self performSelectorInBackground:@selector(performRequest:) withObject:requestGBP];
以这种方式试一试,让我知道为你做的事情!
答案 1 :(得分:1)
检查错误是否 nil ,在这种情况下打印它,它将帮助您理解问题。我还会在这里评论有关编码的评论(通过CodaFi),以及关于更新主线程上的UI(这不是问题的原因,但后来可能会变得讨厌):
[NSURLConnection sendAsynchronousRequest:requestGBP queue:operationQueue completionHandler: ^(NSURLResponse* response, NSData* data, NSError* error)
{
if(error)
{
NSLog(@"%@",error);
}
else
{
// Get the right string encoding:
NSStringEncoding encoding= NSASCIIStringEncoding; // This in case the page will
// not return any encoding.
if(response.textEncodingName)
{
encoding= CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((__bridge CFStringRef) text.encodingName));
// A bit messy right? Don't get lost, read these functions on the
// documentation: http://developer.apple.com/library/ios/#documentation/CoreFoundation/Reference/CFStringRef/Reference/reference.html
}
responseGBP = data;
NSString *json_stringGBP = [[NSString alloc] initWithData:responseGBP encoding: encoding];
self.feedGBP = [parser objectWithString:json_stringGBP error:nil];
NSString *GBP = [NSString stringWithFormat:@"Info Last: %@" feedGBP ObjectForKey:@"value"]];
// Update the UI on main thread:
[myLabel performSelectorOnMainThread: @selector(setText:) withObject: GBP waitUntilDone: NO];
}
}];