我正在使用NSURLSession API异步地从互联网上下载两种类型的csv数据(称为类型A和类型B)的OS X(Yosemite)应用程序。每种类型的csv都有多个请求。每个请求都是自定义类中包含的专用会话。有一个基类请求类和每个类型的子类。 (事后看起来可能不是一个理想的设计,但我认为我的问题无关紧要)。为什么我有时会遇到并发的NSURLSession请求的破坏回复
该应用程序的构建方式使得每种类型的csv数据都以顺序队列的形式下载。每种类型只有一个请求可以同时处于活动状态,但这两种类型都可以同时发生,并且两者都使用主线程用于委托回调。所有这一切通常很好。
我看到的问题是,有时在交通拥堵的情况下,我得到了“交叉听力”,即我有时会得到一个回应B类请求的响应,该类型B请求报告已成功完成,但它包含一些B类CVS线然后有一些类型的A行标记后 - 所以我有时(很少)在我的类型B请求中获得类型A数据。 (或其他方式)。
基本上,它看起来像Apples API中的“切换”逻辑会对哪个传入数据包属于哪个请求/会话感到困惑。两种不同的请求类型转到不同的URL,但它们是相关的,可能它们最终都解析为相同的IP,但我不确定这一点。我想知道,如果它们来自同一个服务器,那么它们可能与数据包标题有关,从而难以确定它们属于哪个请求(我在互联网协议上不够好,不知道这是否是一个明智的猜测) 。如果是这种情况,那么解决方案必须确保所有请求都在一个队列中,以使它们不能同时处于活动状态,但我不想在执行大型体系结构更改之前,我确信没有其他解决方法。
我寻找类似的问题,发现这个老问题(Why is my data getting corrupted when I send requests asynchronously in objective c for iOS?)似乎描述了完全相同的问题,但不幸的是它没有答案。除此之外,我没有发现任何类似的东西,所以我想我在这里做了一些愚蠢的事情,但是在我开始改变架构来修复它之前,知道为什么会出现这个问题会很好。
有没有人看过这个,知道什么原因和解决方法是?
我没有包含任何代码,因为我觉得没有意义,因为它似乎是一个架构问题,如果我添加代码,它将需要很多。不过,如果能帮助我们理解这个问题,我会很乐意补充您的建议。
编辑:
相关(我希望)代码添加到下面。注意对象只有一个镜头。该请求的参数由init方法注入,NSURLSession仅用于单个任务。因此,会话在启动后失效,并在解析数据后释放NSMutableData数组。
-(BOOL)executeRequest {
NSURLSessionConfiguration *theConfig = [NSURLSessionConfiguration ephemeralSessionConfiguration];
NSURLSession *theSession = [NSURLSession sessionWithConfiguration:theConfig delegate:self delegateQueue:[NSOperationQueue mainQueue]];
NSURLRequest *theRequest = [NSURLRequest requestWithURL:self.queryURL cachePolicy: NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:BSTTIMEOUT];
NSURLSessionDataTask *theTask = [theSession dataTaskWithRequest:theRequest];
if(!theTask) {
return NO;
}
[theTask resume];
[theSession finishTasksAndInvalidate];
self.internetData = [NSMutableData dataWithCapacity:0];
return YES;
}
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
[self.internetData appendData:data];
return;
}
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
if((error)||(![self parseData]))
{
self.internetData = nil;
if(!error) {
NSDictionary *errorDictionary = @{ NSLocalizedDescriptionKey : @"Parsing of internet data failed", NSLocalizedFailureReasonErrorKey : @"Bad data was found in received buffer"};
error = [NSError errorWithDomain:NSCocoaErrorDomain code:EIO userInfo:errorDictionary];
}
NSDictionary* ui = [NSDictionary dictionaryWithObject:error forKey:@"Error"];
[[NSNotificationCenter defaultCenter] postNotificationName:[self failNotification] object:self userInfo:ui];
return;
}
[[NSNotificationCenter defaultCenter] postNotificationName:[self successNotification] object:self];
return;
}
请添加一些代码,特别是处理数据接收的代码('-connection:didReceiveData:')。 –
更新:我实现了一个请求队列,可以将csv请求串行化,以便一次只能有一个活动。这似乎解决了我的问题,并且性能可以接受,因为请求数量并不那么高,也没有时间限制。然而,主要问题(为什么会发生这种情况?)仍然未知,因此我不会将此作为答案发布。 – pco494
我终于找到了解决方案,并将其作为未来参考的答案发布。 – pco494