2011-08-11 49 views
1

我正在爲我正在開發的應用程序構建下載管理器功能。作爲一項要求,我們需要支持最多三個並行下載。我看到這個論壇的一些代碼示例使用相同的委託對象並創建NSURLConnection對象的多個實例。這種方法的一個缺點(我認爲,我可能是錯的)是,所有對委託對象的回調都會發生在同一個線程上。這將導致數據包在線程中排隊。我在這裏錯過了什麼。iOS中的並行下載

是否有任何其他方式實現此功能,如做一個NSInvocationQueue,並開始在不同的線程上單獨下載,從而獲得更好的效率。使用這種方法,它會增加很多複雜性,以便跟蹤每次下載的進度,暫停/恢復下載和線程管理。

我打算在單個線程上創建異步請求,並且出於顯而易見的原因不保留同步連接。此外,我正在下載大型視頻文件> 100 MB並將其直接存儲到文件中。我有點不清楚數據包將如何排隊,並且會耗盡內存還是會使主線程無響應。

任何指針或幫助,非常感謝。

感謝

回答

5

由於Tommy已經指出,使用單獨的線程僅用於下載數據通常效率不高。它也比在主線程上使用異步接口NSURLConnection更高的內存開銷,並且失去了很多控制權(不能取消在後臺線程上運行的同步連接)。

你是對的,委託回調將全部在主線程上排隊,但通常情況下,你唯一要做的就是連接數據塊直到下載完成 - 這在計算上非常便宜。

如果您打算在數據下載之後(如創建縮略圖圖像,解析等)使用數據進行耗費大量計算的工作,您可以在連接完成下載後輕鬆地將該工作分派到GCD隊列。這樣,您不會失去對下載過程的控制,可以輕鬆顯示進度或取消正在運行的下載,但仍然不會阻止主線程。

1

Apple的建議是,您使用NSURLConnection與代理異步使用,而不是使用線程和阻塞連接。如果你在同一個線程上使用多個NSURLConnections,那麼數據將全部在同一個線程上返回,但這不是問題。除非您的代碼交織在一起,否則數據不會交織在一起,並且不會影響網絡性能。

僅僅爲了獲取數據而啓動線程效率較低,特別是在電池利用率方面,而不是簡單地在同一線程中使用多個NSURLConnections。

0

您應該查看HTTP客戶端庫,如ASIHTTPRequest

ASIHTTPRequest使用隊列處理併發請求,您可以輕鬆地限制併發。從ASIHttpRequest借實施例的代碼:

- (IBAction)grabURLInTheBackground:(id)sender 
{ 
    if (![self queue]) { 
     [self setQueue:[[[NSOperationQueue alloc] init] autorelease]]; 
    } 

    NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"]; 
    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url]; 
    [request setDelegate:self]; 
    [request setDidFinishSelector:@selector(requestDone:)]; 
    [request setDidFailSelector:@selector(requestWentWrong:)]; 
    [[self queue] addOperation:request]; //queue is an NSOperationQueue 
} 

- (void)requestDone:(ASIHTTPRequest *)request 
{ 
    NSString *response = [request responseString]; 
} 

- (void)requestWentWrong:(ASIHTTPRequest *)request 
{ 
    NSError *error = [request error]; 
} 

修改[NSOperationQueue maxConcurrentOperationCount]改變併發性。

+0

從該網站,似乎該圖書館不再被維護。 – Scorchio