我正在为我正在处理的应用构建下载管理器功能。作为一项要求,我们需要支持最多三个并行下载。我看到了这个论坛的一些代码示例使用相同的委托对象并创建NSURLConnection对象的多个实例。这种方法的一个缺点(我认为,我可能是错的)是,委托对象的所有回调都会发生在同一个线程上。这将导致数据包在线程上排队。我在这里错过了什么。
是否有其他方法可以实现此功能,例如执行NSInvocationQueue并在不同的线程上启动单独下载,从而获得更高的效率。使用这种方法,它为跟踪每次下载,暂停/恢复下载和线程管理的进度增加了很多复杂性。
我打算在单个线程上创建异步请求,而不是出于显而易见的原因保持同步连接。我也在下载大型视频文件> 100 MB并将其直接存储到文件中。我有点不清楚数据包是如何排队的,我会用完或内存还是会使主线程没有响应。
非常感谢任何指示或帮助。
由于
答案 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]以更改并发性。