gpt4 book ai didi

macos - 为什么我有时会收到并发 NSURLSession 请求的错误回复

转载 作者:行者123 更新时间:2023-12-03 16:45:37 24 4
gpt4 key购买 nike

我正在开发一个 OS X (Yosemite) 应用程序,它使用 NSURLSession API 从互联网异步下载两种类型的 csv 数据(称为 A 型和 B 型)。每种 csv 类型都有多个请求。每个请求都是它自己的专用 session ,封装在自定义类中。每种类型都有一个基本请求类和一个子类。 (事后看来,这可能不是一个理想的设计,但我认为与我的问题无关)。

该应用程序的构造使得每种类型的 csv 数据都按顺序队列下载。每种类型一次只能有一个请求处于事件状态,但两种类型可以同时发生,并且都使用主线程进行委托(delegate)回调。所有这些通常都可以正常工作。

我看到的问题是,有时在流量很大的情况下,我会得到“交叉听证”,即我有时会收到对 B 类请求的响应,该请求报告为已成功完成,但它包含许多 B 类 cvs 行,并且然后在之后标记一些 A 类型行 - 所以我有时(很少)在 B 类型请求中获取 A 类型数据。 (或相反)。

基本上,Apple API 中的“切换”逻辑似乎对哪个传入数据包属于哪个请求/ session 感到困惑。两种不同的请求类型发送到不同的 URL,但它们是相关的,并且它们最终可能都解析为相同的 IP,我对此不确定。我想知道如果数据包头来自同一台服务器,是否可能存在与数据包头相关的内容,这使得很难确定它们属于哪个请求(我对互联网协议(protocol)的了解不够好,不知道这是否是一个合理的猜测) 。如果是这种情况,那么解决方案必须是确保所有请求都在一个队列中,以便它们不能同时处于事件状态,但在我确信没有其他解决方法之前,我不想进行如此大的架构更改。

我寻找类似的问题,发现这个老问题( Why is my data getting corrupted when I send requests asynchronously in objective c for iOS? )似乎描述了完全相同的问题,但不幸的是它没有答案。除此之外,我没有发现任何类似的东西,所以我想我在这里做了一些愚蠢的事情,但在我开始更改架构来修复它之前,最好知道为什么会出现这个问题。

有人以前见过这种情况并知道原因和解决方法是什么吗?

我没有包含任何代码,因为我觉得没有意义,因为它似乎是一个架构问题,如果我添加代码,则需要很多代码。不过,如果有助于理解这个问题,我很乐意添加您的建议。

编辑:

下面添加了相关(我希望)代码。注意对象仅是一次拍摄。请求的参数由 init 方法注入(inject),并且 NSURLSession 仅用于单个任务。因此, session 在启动后失效,并且 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;
}

最佳答案

首先:您不应该为每个请求创建一个新 session 。这不再是 session 了。来自 docs :

With the NSURLSession API, your app creates one or more sessions, each of which coordinates a group of related data transfer tasks. For example, if you are writing a web browser, your app might create one session per tab or window, or one session for interactive use and another session for background downloads. Within each session, your app adds a series of tasks, each of which represents a request for a specific URL (following HTTP redirects if necessary).

第二:你将 session 等存储在哪里,这样它就不会被释放?

您的主要问题:显然您在请求可能正在运行时启动了新请求。但是你只有一个 NSMutableData 实例接收 -URLSession:task:didReceiveData: 中的数据:许多请求,一个存储……当然,这会混淆。

关于macos - 为什么我有时会收到并发 NSURLSession 请求的错误回复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33927998/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com