了解GCD块内[NSData dataWithContentsOfURL:URL]的行为

时间:2013-08-28 08:31:03

标签: iphone ios objective-c xcode ios6

以下问题/陈述仅限于我的理解,如果我错了,请告诉我。

来自:Issue with GCD and too many threads

转发到jackslash的答案,我想大多数开发人员都习惯使用[NSData dataWithContentsOfURL:URL],这肯定会阻塞(直到完成)。如果你通过URL获取一些小细节,这可能是理想的。但是在多个进程的情况下(我的意思是在下载多个文件时),GCD必须创建许多线程,并不是下载数据的完美方式。

因此,一些专家建议使用名为[NSURLConnection sendAsynchronousRequest:queue:completionHandler:的GCD抽象来处理这种情况(也是理想的)。

我唯一的问题是,[NSURLConnection sendAsynchronousRequest:queue:completionHandler: 在创建新主题方面如何优先于 NSData dataWithContentsOfURL:URL]并阻止我们被阻止?

非常感谢您提供的任何答案。

2 个答案:

答案 0 :(得分:3)

你的问题并不是关于GCD:它是关于同时下载多个文件的最佳策略。

最好的策略就是不要这样做。试图同时下载100个单独的文件是一个坏主意,特别是如果用户处于蜂窝连接(他们可能是)。你认为dataWithContentsOfURL通常也不是一个好主意是正确的。

那就是说,这里有一个中间立场。如果有办法告诉iOS“一次下载X个文件,但不超过那个”,那将是很好的。为此,我们可以使用NSOperationQueue。操作队列包含许多操作并将它们放入队列(在这种情况下是在后台运行)。例如:

NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
[operationQueue setMaxConcurrentOperationCount:3];
[operationQueue addOperations:@[download1, download2, download3] waitUntilFinished:NO];

这里我们创建了一个可以支持三个同时下载的操作队列。使用操作队列的优点应该是显而易见的。许多开发人员选择使用像AFNetworking这样的库来帮助他们管理下载,并且有很多指南可以在操作队列中同时使用它和NSURLConnection

答案 1 :(得分:1)

sendAsynchronousRequest:queue:completionHandler:不使用GCD进行实际下载。传入的队列仅用于执行完成块。下载本身将在其内部实现中使用低级异步套接字API,因此不会有任何阻塞或不必要的线程创建。