NSURLResponse Content-Length在运行并发下载时实际数据的大小不匹配



我有一个UITableView,当一个单元格被选中时,我调用一个服务从web服务异步下载一个PDF文件。它工作得很好,直到您直接选择多个单元格一个接一个(单独),然后事情开始出错。

下面是一些(精简的)代码来说明:

内部MasterViewController.m:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    //To uniquely identify this field, I build a simple string using the indexPath.
    NSString *key = [[NSString alloc]initWithFormat:@"%d.%d",pIndex.section,pIndex.row];
    //Use a pre-populated NSDictionary to specify the file I want from the server.
    NSString *reportID = [reportDictionary valueForKey:key];
    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/RequestReportWithID",myConnectionObject.ServiceURL]];
    NSMutableDictionary *body = [[NSMutableDictionary alloc] initWithObjectsAndKeys:reportID, @"reportID", nil];
    NSData *requestData = [NSJSONSerialization dataWithJSONObject:dic options:0 error:nil];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [request setHTTPMethod:@"POST"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [request setValue:[NSString stringWithFormat:@"%d", [requestData length]] forHTTPHeaderField:@"Content-Length"];
    [request setHTTPBody: requestData];
    //Create a new object as delegate to receive the data, also add the key to assist with identification.
    ReportDownloader *newReportDownloader = [[ReportDownloader alloc]initWithDelegate:self andKey:key];
    NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:newReportDownloader];
    if (connection)
    {
        //Nothing to do here, request was made.
    }
}

内部ReportDownloader.m:

long long expectedReportSize;
NSString *key;
NSData *thisReport;
-(NSObject*)initWithDelegate:(NSObject*)pDelegate andKey:(NSString*)pKey
{
    myTypedDelegate = (MasterViewController*)pDelegate;
    Key = pKey;
    return self;
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    expectedReportSize = [response expectedContentLength];
    NSLog(@"Key:%@, Expected Size=%lld bytes",Key, [response expectedContentLength]);
    thisReport = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{
    [thisReport appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
{
    //Here is where things go wrong...
    NSLog(@"Key:%@, Actual Size=%ld bytes",Key, (unsigned long)[thisReport length]);
}

上面的代码可以很好地用于单个报告。在快速线上,它可以为3-4个报告工作,但尝试做更多,预期长度开始与实际长度不匹配。我不明白为什么yyyyy....

查看上面代码生成的输出:(注意只有indexPath 1.1的报告被正确下载)

Key:1.0, Expected Size=304006 bytes
Key:1.3, Expected Size=124922 bytes
Key:1.0,   Actual Size=369494 bytes
Key:1.3,   Actual Size=380030 bytes
Key:1.2, Expected Size=179840 bytes
Key:1.4, Expected Size=377046 bytes
Key:1.2,   Actual Size=114376 bytes
Key:1.5, Expected Size=175633 bytes
Key:1.4,   Actual Size=180558 bytes
Key:1.5,   Actual Size=274549 bytes
Key:1.1, Expected Size=443135 bytes
Key:1.1,   Actual Size=443135 bytes

当尝试打开PDF文档时,数据损坏被确认,所有文件的数据大小与预期的contentlength不匹配而失败。

我对这种行为完全感到困惑,我希望我犯了一个明显的错误,有人在这里发现它。

我创建ReportDownloader类的主要原因是为了避免这样的问题。

提前感谢谁花时间扫描我的代码!

好的,这个问题的解决方案可以在这里找到:https://stackoverflow.com/a/1938395/1014983这个答案由James Wald,虽然不是问题的公认答案,完全解决了我所有的问题与多个同步异步NSURLConnections。

如果你在实现上需要帮助,请告诉我,但这很简单。

相关内容

  • 没有找到相关文章

最新更新