1

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

是否有任何其他方式来实现此功能,例如执行 NSInvocationQueue 并在不同的线程上开始单独下载,从而获得更好的效率。使用这种方法,它增加了跟踪每次下载进度、暂停/恢复下载和线程管理的复杂性。

我计划在单个线程上创建异步请求,并且出于明显的原因不保持同步连接。此外,我正在下载大于 100 MB 的大型视频文件并将其直接存储到文件中。我有点不清楚数据包将如何排队,我会用完内存还是会导致主线程无响应。

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

谢谢

4

4 回答 4

5

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

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

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

于 2011-08-11T04:37:07.733 回答
1

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

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

于 2011-08-11T04:25:04.530 回答
0

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

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

于 2011-08-11T04:24:05.467 回答
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] 以更改并发。

于 2011-08-11T05:12:39.277 回答