GCD网络请求在iOS 4上失败

时间:2012-03-22 20:18:26

标签: ios4 nsurlconnection grand-central-dispatch

我的应用程序中有以下代码从我的API加载一些数据。它工作得很好,实际上在iOS 5中很棒,但在iOS 4上,我得到的状态为204的响应很多。

这只发生在iOS 4上,这可能被视为API错误,但它在浏览器,Rested.app,iOS 5等上运行良好...只有iOS 4失败,它在模拟器中失败并在设备上(iPhone 4)。

每次将单元格加载到表格视图中时,我都会调用此代码。我有一个带有加载状态的核心数据对象,最初设置为no,如果没有加载我执行此代码,如果已加载,我跳过此代码。同时我在表视图的单元格内显示一个微调器。

我确信这是iOS 4上GCD中多个请求的问题。

任何人都可以发现我的代码段有什么问题吗?

-(void)myFunction{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // query users participations (Network)

        NSError * _urlError = nil;
        NSString * url = [NSString stringWithFormat:@"my api url"];
        NSMutableURLRequest * loginHTTPRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
        [loginHTTPRequest setValue:@"application/json" forHTTPHeaderField:@"Accept"];

        NSLog(@"Description: %@", [loginHTTPRequest description]);

        NSHTTPURLResponse   * _responseHeaders  = nil;
        NSData              * responseData      = [NSURLConnection sendSynchronousRequest:loginHTTPRequest 
                                                                        returningResponse:&_responseHeaders 
                                                                                    error:&_urlError];
        if(_urlError != nil){
            dispatch_async( dispatch_get_main_queue(), ^{
                // alert network connection error
            });
            return;
        }

        NSString *json_string = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];

        SBJsonParser *parser = [[SBJsonParser alloc] init];
        NSDictionary * jsonData = [NSDictionary dictionaryWithDictionary:[parser objectWithString:json_string]];
        [json_string release];
        [parser release];

        dispatch_async( dispatch_get_main_queue(), ^{
            // here [_responseHeaders statusCode] keeps returning 204 and there is nothing in responseData

            // do some Core Data stuff
        });

    });
}

更新

注意,即使重复使用for循环调用此代码也能正常工作,问题是当我从tableView调用此方法时:cellForRowAtIndexPath:

我将Core Data对象的属性“isLoaded”设置为NO,并在远程加载时更改为YES。当我的tableview的数据源加载每个对象的单元格时,如果对象的“isLoaded”属性为NO,则tableView:cellForRowAtIndexPath:方法调用此函数。

我怀疑问题可能是因为在加载和重新加载表时会发生2次或更多次API同时调用。来自api的每个成功加载都会为该tableview调用reloadData。

这让我有一个带有微调器的预先填充的tableview,并在我的数据中异步加载,因为我需要它在屏幕上这很好,因为我可以有效地使用NSFetchedResultsController延迟加载我的对象核心数据。

(我有一个端点,我的所有对象都返回一个对象id数组 - 我创建只有ID的Core Data对象,所有剩余的数据,名称,日期等等......在需要之前不会加载)。

当我开始滚动创建/重用的新单元时,调用此方法,它们总是得到200响应数据。它只是导致这个“阻塞”的第一次加载。

2 个答案:

答案 0 :(得分:1)

我想我发现了问题,我在异步GCD线程上执行同步请求,并且由于某种原因发生了超时,但仅在iOS 4中的请求中,可能会发送标题与iOS 4略有不同,这导致API需要更长的时间才能响应?或者在异步线程上同步发送的多个请求(同时为毫秒)请求在发送之前在系统中发生冲突?

无论如何......这似乎不是调用google.com甚至我自己的私人服务器的情况,所以它必须与标题和多个请求有关...

我正在使用来自github的asi http,并且它的工作效率更高,现在我没有使用GCD来处理这些请求,只是一个ASI队列。

关于在异步GCD线程上执行的iOS 4同步请求的最终想法是否有可能超时并且状态为204的早期返回?

答案 1 :(得分:0)

好的 - 如果它是https,那么你可能无法使用sendSynchronousRequest。文档指出像[NSURLConnection connection:didReceiveAuthenticationChallenge:]这样的东西不会调用一些关键的东西,即:

  

如果需要进行身份验证才能下载请求,则必须将所需的凭据指定为URL的一部分。如果身份验证失败或缺少凭据,则连接将尝试在没有凭据的情况下继续。

老实说,我仍然对在iOS5上工作感到惊讶。我认为你必须使用异步方法来至少调试它以找出发生了什么。