iOS中的并行下载

时间:2011-08-11 04:21:13

标签: iphone objective-c ios ipad download-manager

我正在为我正在处理的应用构建下载管理器功能。作为一项要求,我们需要支持最多三个并行下载。我看到了这个论坛的一些代码示例使用相同的委托对象并创建NSURLConnection对象的多个实例。这种方法的一个缺点(我认为,我可能是错的)是,委托对象的所有回调都会发生在同一个线程上。这将导致数据包在线程上排队。我在这里错过了什么。

是否有其他方法可以实现此功能,例如执行NSInvocationQueue并在不同的线程上启动单独下载,从而获得更高的效率。使用这种方法,它为跟踪每次下载,暂停/恢复下载和线程管理的进度增加了很多复杂性。

我打算在单个线程上创建异步请求,而不是出于显而易见的原因保持同步连接。我也在下载大型视频文件> 100 MB并将其直接存储到文件中。我有点不清楚数据包是如何排队的,我会用完或内存还是会使主线程没有响应。

非常感谢任何指示或帮助。

由于

4 个答案:

答案 0 :(得分:5)

正如Tommy指出的那样,使用单独的线程来下载数据通常效率不高。它还比在主线程上使用NSURLConnection的异步接口具有更高的内存开销,并且您失去了很多控制权(您无法取消在后台线程上运行的同步连接)。

你是对的,委托回调将全部排在主线程上,但通常,你唯一要做的就是连接数据块直到你的下载完成 - 这在计算上非常便宜。

如果您打算在下载数据之后对数据执行昂贵的计算(如创建缩略图,解析等),则可以在连接完成下载后轻松将该工作分派到GCD队列。这样,您就不会失去对下载过程的控制,可以轻松显示进度或取消正在运行的下载,但仍然不会阻止主线程。

答案 1 :(得分:1)

Apple建议您使用NSURLConnection与委托异步,而不是使用线程和阻塞连接。如果在同一个线程上使用多个NSURLConnections,那么数据将在同一个线程上返回,但这不是问题。除非您的代码交织在一起,否则数据不会以某种方式交织在一起,并且不会对网络性能产生影响。

仅仅为获取数据的过程启动线程效率较低,尤其是在电池利用率方面,而不是在同一线程上简单地使用多个NSURLConnections。

答案 2 :(得分:0)

会有所帮助 - http://allseeing-i.com/ASIHTTPRequest/

对于并行下载,您可以使用ASINetworkQueue。

答案 3 :(得分:0)

您应该查看像ASIHTTPRequest这样的HTTP客户端库。

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]以更改并发性。