我正在使用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