【发布时间】:2013-03-27 11:52:34
【问题描述】:
I have a UITableView, when a cell is selected, I make a service call to asynchronously download a PDF file from a web service.效果很好,直到您一个接一个地(单独)选择多个单元格,然后事情开始向南......
这里有一些(精简的)代码来澄清:
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 份报告,但尝试做的不止于此,预期长度开始与实际长度不匹配。而且我不明白为什么yyyy....
查看上面代码生成的输出: (请注意,只有 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 文档时确认数据损坏,所有文件的数据大小与预期内容长度不匹配都会失败。
我对这种行为完全感到困惑,我希望我犯了一个明显的 n00b 错误,并且这里有人发现了它。
我制作 ReportDownloader 类的主要原因是为了避免类似的问题。
提前感谢花时间扫描我的代码的人!
【问题讨论】:
-
我有答案,只是没有足够的代表在 5 小时内回答我自己的问题。
-
嗨,我也有同样的问题。你能告诉我如何解决这个问题吗??
-
嗨,Apple,我在下面添加了答案。
标签: asynchronous nsurlconnection nsurlrequest content-length simultaneous-calls