2010-07-13 123 views
6

我正在將表格視圖單元格中的圖像下載到屏幕上。出於UX的原因,我開始下載- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath中的圖像。我不等到表視圖完成滾動。當表格視圖單元格被設置時,我開始下載我沒有的圖像。但是,它們似乎沒有完全下載,直到表視圖停止移動。只要它停止移動,圖像幾乎立即下載。NSURLConnection是否阻止主/ UI線程

無論如何要使用NSURLConnection它沒有被主UI線程阻塞?或者,有沒有辦法在桌面視圖滾動時快速下載這些圖像。

**編輯**

爲了證明NSURLConnection的慢我用NSThread在不同的線程脫離了新的選擇。然後我下載數據並回調到創建UIImage的主線程,並在表格視圖中顯示它。這種方法工作速度更快。

就我個人而言,我認爲NSURLConnection會被引入UITableView滾動阻塞的事件循環中。

+0

用戶能夠以比電話能夠擊中網絡並下載圖像更快的速度滾動表格。對我來說聽起來很正常... – psychotik 2010-07-13 03:50:57

+0

我剛剛通過分離新的NSThread實現了同樣的解決方案,並且它的下載速度更快。 – rickharrison 2010-07-13 04:46:28

+1

絕對下載使用事件循環。這聽起來似乎合理,滾動是以某種方式關閉它。 – JeremyP 2010-07-13 07:58:44

回答

2

我以前也遇到過這個問題。當scrollView被滾動時,NSURLConnection的異步委託方法不會觸發。雖然下載在後臺工作,但您的主線程不會被通知新圖像。就像你一樣,我相信這個問題與scrollview在一個內部NSRunLoop中使用不同的RunLoopMode滾動有關。我一直在與蘋果員工討論這個問題,讓他們看看我的代碼,但我們無法找到解決方案。

另一方面Jeff LaMarche在他的博客上有this post,他在那裏做同樣的事情,並且它按預期工作。我一直無法弄清楚他做了什麼不同(主要是因爲沒有時間),但這可能值得一看。

1

如果你的意思是「NSURLConnection在主線程上執行嗎?」,那麼是的,我相信是這樣的。連接打開並且委託方法在主線程上執行。我還沒有找到任何文檔來建議,您可以通過調試來驗證它。

我認爲你的假設UITableView滾動阻塞主運行循環中的NSURLConnection回調是正確的。

您已經發布了一個解決方案,爲您的選擇器產生一個線程。另一種方法是執行您下載的NSOperations,它有幾個好處:

  • 如果強行操作,同時運行(見Dave Dribin's excellent post on this),你可以限制同時下載的數量,這可能是可取的如果你的桌子上有大量的圖片。您說您的下載「幾乎是即時」發生,但如果您的用戶連接速度較慢並且您的桌面包含大量圖像,則可能不是這種情況。
  • 如果用戶執行的操作使圖像下載無關緊要(如執行其他搜索),則可以取消所有操作。

我使用的Dave Dribin的方法強制連接在主線程上執行,但這可能對您的目的沒有必要 - 您可以使用當前的方法調用回主線程你的圖片下載後。

22

NSDefaultRunLoopMode vs NSRunLoopCommonModes對於爲什麼所有的下載委託通知排隊一個很好的解釋,但在使用此主線程變化時滾動下載:

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

這樣:

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request 
                   delegate:self 
                 startImmediately:NO]; 
[connection scheduleInRunLoop:[NSRunLoop currentRunLoop] 
         forMode:NSRunLoopCommonModes]; 
[connection start]; 
+0

太棒了,謝謝。 – Sam 2012-12-04 18:00:46