Asynchronous NSURLResponse内容长度不匹配运行并发下载时实际数据的大小

Asynchronous NSURLResponse内容长度不匹配运行并发下载时实际数据的大小,asynchronous,nsurlconnection,nsurlrequest,content-length,simultaneous-calls,Asynchronous,Nsurlconnection,Nsurlrequest,Content Length,Simultaneous Calls,我有一个UITableView,当选择一个单元格时,我会进行一个服务调用,以从web服务异步下载PDF文件。它工作得很好,直到您直接依次选择多个单元格(单个),然后情况开始恶化 下面是一些(精简的)代码来澄清: 内置MasterViewController.m: - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { //To uniquely identi

我有一个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.
    }
}
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]);
}
内部报告下载程序.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.
    }
}
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个报告,但如果尝试做得更多,预期的长度就会开始与实际长度不匹配。我不明白为什么

请参见上面代码生成的输出: (请注意,仅正确下载了indexPath 1.1的报告)

在尝试打开PDF文档时确认数据损坏,因为所有文件的数据大小与预期的内容长度不匹配而失败

我完全被这种行为所迷惑,我希望我犯了一个明显的n00b错误,并且这里有人发现了它

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


提前感谢那些花时间扫描我代码的人

好的,这个问题的解决方案可以在这里找到: James Wald的回答虽然不是问题的公认答案,但完全解决了我在多个同步异步NSURL连接中的所有问题


如果您在实施过程中需要帮助,请告诉我,但这很简单。

我有答案,只是没有足够的代表在5小时内回答我自己的问题。嗨,我也有同样的问题。你能告诉我如何解决这个问题吗?嗨,苹果,我在下面补充了答案。