2013-04-03 58 views
1

我有一個iPad應用程序,我使用NSURLConnection進行異步調用。在某些情況下,我會收到連接中的所有響應數據:didReceiveData:,但是connectionDidFinishLoading永遠不會被稱爲。沒有錯誤。這有些隨意,因爲在其他時間完成相同的迴應。NSURLConnection connectionDidFinishLoading不隨機調用

,我的類的工作方式是,大約20個請求在使用行發送:

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES]; 

然後我就等着他們回來。這是創建多個請求的有效方法嗎?

以下是未完成回覆的示例標題。與完成的響應的標題無法區分。問題的

>Keep-Alive: timeout=5, max=100 
>Transfer-Encoding: Identity 
>Server: Apache/2.2.9 (Unix) mod_ssl/2.2.9 OpenSSL/0.9.8b mod_jk/1.2.26 
>Content-Type: application/json;charset=UTF-8 
>Connection: Keep-Alive 
>Date: Wed, 03 Apr 2013 05:25:32 GMT 
>Cache-Control: private, no-transform, max-age=600 

一個奇怪的現象是,我開始檢查使用預期的內容長度:

long long download_size =[response expectedContentLength]; 

內容長度的HTTP頭永遠不會設置。當請求失敗時,download_size爲-1(預期),當相同的請求沒有失敗時,download_size被設置爲某個數字。但是,在很多情況下,download_size沒有設置,並且響應也沒有失敗。

+0

你是在主線程上執行此操作嗎? –

回答

1

這不是發起20個請求一個偉大的方式,因爲:

  1. 的要求同時工作,因此如果你沒有一些類,它將所有的響應數據,並從類似個人請求,你的應用可能會混淆來自各種請求的響應數據;

  2. 因爲它們同時發生,並且由於iOS只允許對給定服務器發出五個併發請求,所以它會延遲(並可能超時)其他服務器。

你有一堆不同的方法,但你可能:

  • 你可能想要做一個後臺排隊這個網絡的東西;

  • 如果你想併發操作(並有這樣做可觀察到的性能優勢),你可以使用NSOperationQueue有併發操作,但限制多少併發操作正在進行(4或5)配合使用的maxConcurrentOperationCount 。但是,如果您在這些後臺操作中使用同步網絡操作,則這個過程是微不足道的,但如果您在後臺隊列中使用自己的委託方法使用異步網絡操作,則會出現令人驚訝的複雜情況。如果您確實需要(a)使用您自己的委託方法(例如,更新進度視圖,流式協議等)來使用異步網絡調用;和(b)你想享受併發操作,使用AFNetworking會比你自己寫的要容易得多。我經歷了這個自己寫作的練習,但做了一次這樣的練習,現在我更加明白AFNetworking帶來了什麼。

當然,你可以通過管理自己的待處理網絡請求的陣列避開這一切,開始的第一個,並有connectionDidFinishLoading和/或didFailWithError開球隊列中的下一個,但你失去了併發的性能收益。但這是一個簡單的解決方法。

+0

我已更改我的應用程序爲每個連接創建一個新類。連接委託類生存的時間足以將成功或失敗傳遞給我的視圖控制器。感謝您的建議 - 我想知道你在哪裏得到的信息,iOS只允許五個併發請求。 – minus

+1

@CarolineM在[MVCNetworking](https://developer.apple.com/library/ios/#samplecode/MVCNetworking/Introduction/Intro.html#//apple_ref/doc/uid/DTS40010443)中,Apple使用了四個。當我進行基準測試時(通過提高最大併發性來改善性能),我發現總體性能隨着最大併發數的增加而改善,當最大併發數達到5時,總體性能得到改善,但不止如此,如果花費超過1分鐘啓動他們會失敗)。我在S.O.上讀過某處。 5是單一主機的iOS限制(我在Apple文檔中沒有看到),但這與我所經歷的一致。 – Rob

+0

您通常只有在下載大文件或過慢連接時纔會遇到此問題(在模擬器上使用網絡調節器或關閉wifi);即在後面的操作有機會開始之前需要超過一分鐘才能完成第一次連接。 – Rob

1

我希望你使用單獨的對象在這裏。你在說

NSURLConnection *connection = 
    [[NSURLConnection alloc] initWithRequest:request 
    delegate:self startImmediately:YES]; 

那麼,我當然希望那些是20個不同的self對象。您不能期望這可以與單個對象同時充當所有20個請求的委託!

+0

我認爲這些回覆會排隊。我正在改變我的實施來測試這個。 – minus

+0

我有一個類可以幫助你:看到MyDownload類在這裏http://www.apeth.com/iOSBook/ch37.html#_http_requests – matt

+0

但是,我也會建議你不要阻塞線程/聯網系統試圖一次完成20次下載! – matt

相關問題