Iphone NSURLConnection异步间歇性返回null

Iphone NSURLConnection异步间歇性返回null,iphone,ios,objective-c,asynchronous,nsurlconnection,Iphone,Ios,Objective C,Asynchronous,Nsurlconnection,考虑到下面的代码,我将我的应用程序从同步调用移动到异步调用,以停止UI冻结除了一些小细节外,一切正常 当进行同步调用时,它们总是返回一个值(即使需要很长时间(5或6秒)) 但现在: 异步调用有时非常快,有时需要8或9秒(我也有光纤互联网) 他们获取的文本数据有时似乎不返回,或者在myLabel文本最终设置为“NULL”时超时-我知道这不是我使用API的网站,因为它总是为同步调用和浏览器返回值 有什么想法吗? 谢谢 编辑:来自日志的错误响应为:响应: 错误:(空) EDIT::我还看到日志窗口中打

考虑到下面的代码,我将我的应用程序从同步调用移动到异步调用,以停止UI冻结除了一些小细节外,一切正常

当进行同步调用时,它们总是返回一个值(即使需要很长时间(5或6秒)) 但现在:

  • 异步调用有时非常快,有时需要8或9秒(我也有光纤互联网)

  • 他们获取的文本数据有时似乎不返回,或者在myLabel文本最终设置为“NULL”时超时-我知道这不是我使用API的网站,因为它总是为同步调用和浏览器返回值

  • 有什么想法吗? 谢谢

    编辑:来自日志的错误响应为:响应: 错误:(空)


    EDIT::我还看到日志窗口中打印了很多“应该无法到达这里”?!这不是我的NSLog代码的一部分

    取决于您的队列,您如何初始化您的
    操作队列以及在何处初始化
    ?
    更重要的是,何时调用异步连接

    如果从具有动画的UIView(如tableView或scrollView)中调用它们,则当table/scrollView滚动时,队列将以这种方式运行

    为了能够调试更多信息,您需要
    NSLog(@“Response:%@\r\n错误:%@),Response,error)

    但根据我的经验,我高度怀疑是第一种情况导致了这种情况,您也可以尝试使用默认队列而不是自己的队列,类似这样的情况(不推荐,但可能有助于调试):

    编辑1:添加一个简单的代码更改,使事情变得更简单

    因此,正如我所怀疑的,您正在从动画视图中触发调用,这有时会导致延迟,我要做的是将异步连接还原为同步连接,但在后台线程上调用它们

    下面是事情的外观(未经测试的代码,可能包含错误或需要一些调整)

    将调用移到一个新方法中,将其称为performRequest:(URLRequest*)req

    -(void)性能请求:(URLRequest*)请求{

    }

    每当您需要执行网络请求时,(从动画中,等等…) 您只需在后台线程中调用它,如下所示

    //Place this right after you create your requestGBP request
    [self performSelectorInBackground:@selector(performRequest:) withObject:requestGBP];
    
    这样试试,让我知道你的情况

    检查错误是否为零,在这种情况下打印它,它将帮助您理解问题。在这里,我还将介绍有关编码(由CodaFi编写)和更新主线程上的UI的评论(这不是问题的原因,但以后可能会变得烦人):


    您确定得到的响应总是ASCII编码的吗?解码失败时,NSString返回nil。因此,请检查NSError,可能您没有正确发送某些内容。请注意,应在主线程上更新标签:[myLabel performSelectorOnMainThread:@selector(setText:)withObject:GBP waitUntilDone:NO];。NSLog(@“%@,[Error localizedDescription])记录错误;Always returns null(必须无错误)将尝试PerformSelectorOnInnom对ASCII编码不确定,但它在使用同步调用和ASCII enc之前从未失败过?谢谢Ramy,以下是我从日志中得到的响应:response:error:(null)和另一个示例:response:error:(null)text.encodingName应该在这里是什么变量?谢谢在nil目标上执行的方法永远不会执行,返回值为nil。所以有一个级联效应,你不知道是什么“失败”(返回nil)方法导致了这个问题。尝试在块内放置断点,查看从何处获得nil字符串(json_stringGBP、feedGBP或GBP?),并让我们知道。似乎我们现在知道问题的根源,正如您所说的,太混乱了;)我有一个想法来清理一下,我会编辑我的答案,因为我会包括代码片段,给我一个secCool!我一试这个就会回来让你知道谢谢@JohnWoods这真的很简单1.因为异步调用可以在主线程上运行,但在队列中运行,所以基本上它被放在NSOperationQueue中,完成后执行给定的块,而不是在单独的线程中运行。2.因为异步调用在NSOperationQueues内部运行,NSOperationQueues将在与视图动画相同的队列中运行,导致它在视图动画时阻塞。3.您可能想更多地了解GCD,但它基本上是一个基于线程构建的更抽象的实现。4.他们几乎一样(是的!)太棒了,所以每当我想在主线程上异步运行一些东西时,我就可以调用这个块!?酷。再次感谢您的帮助,投了赞成票并回答:)是的,这就是您在主线程上运行东西的方式,建议只在UI更新时使用,这就像是响应应用程序的“神奇药丸”。)
    [NSURLConnection sendAsynchronousRequest:requestGBP queue:[NSOperationQueue currentQueue] completionHandler: ^(NSURLResponse* response, NSData* data, NSError* error)
    
    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];
    
    [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];
        }
    }];