使用单个共享后台线程进行iOS数据处理?

我有一个应用程序,我正在从networking上下载一些资源,并对每一个进行一些处理。 我不希望这个工作在主线程上发生,但是它是非常轻量级和低优先级的,所以它们都可以在同一个共享工作线程上发生。 这似乎是一件好事,因为需要设置和拆除所有这些工作线程(这些线程都不会很长,等等)。

令人惊讶的是,似乎没有一种简单的方法可以让所有这些工作都在一个共享的线程上进行,而不是为每个任务产生一个新的线程。 实现并发的途径多年来似乎已经出现,这很复杂。 (显式NSThreadsNSOperationQueue ,GCD等)

我是否高估了产生所有这些线程的开销? 我应该只是没有汗水,并使用更容易的每个任务的方法? 使用GCD,并假定它比我更聪明的线程(重新)使用?

使用GCD – 这是目前的官方build议,比任何其他解决scheme都less。 如果你明确地需要你传入的东西串行发生(也就是在一个线程上),那么你可以实现这一点,但是改变它可能更聪明

 [self doCostlyTask]; 

至:

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^() { [self doCostlyTask]; dispatch_async(dispatch_get_main_queue(), ^() { // most UIKit tasks are permissible only from the main queue or thread, // so if you want to update an UI as a result of the completed action, // this is a safe way to proceed [self costlyTaskIsFinished]; }); }); 

这基本上告诉操作系统“做这个代码低优先级,无论它是最有效的做到这一点”。 您发布到任何全局队列的各种内容可能会或可能不会在彼此相同的线程上执行,也可能不会在调度它们的线程上执行,并且可能并发或不可能同时发生。 操作系统应用它认为最优的规则。

博览会:

GCD是苹果公司实现的线程池,并且同时引入了闭包(作为“块”)以使其可用。 所以^(C-style args){code}语法是一个块/闭包。 也就是说,它的代码加上代码引用的任何variables的状态(受到警告)。 您可以自己存储和调用块,不需要GCD知识或使用。

dispatch_async是一个GCD函数向指定的队列发出一个块。 它在某个线程上执行某个时间块,并以最佳方式应用未指定的内部规则。 它会根据诸如你有多less核心,每一个是多么繁忙,目前对节能(这可能取决于电源)的想法,这个特定的CPU的电源成本如何计算等因素来判断。

所以就程序员的开发而言,块将代码变成可以作为parameter passing的东西。 GCD允许您请求根据操作系统可以pipe理的最佳调度来执行块。 块是非常轻量级创build和复制 – 比NSOperation更多。

在上面的例子中,GCD超越了基本的asynchronous调度(例如,你可以做一个并行循环并等待它在一次调用中完成),但是除非你有特定的需求,否则可能不是那么重要。

令人惊讶的是,似乎没有一种简单的方法可以让所有这些工作都在一个共享的线程上进行,而不是为每个任务产生一个新的线程。

这正是GCD所要做的。 GCD维护一个可用于执行任意代码块的线程池,并且负责pipe理该池以便在任何硬件上获得最佳结果。 这样可以避免不断创build和销毁线程的代价,同时也使您无需弄清楚有多less处理器可用。

Tommy提供了正确的答案,如果你真的关心只有一个线程应该使用,但它听起来像你只是试图避免每个任务创build一个线程。

实现并发的途径多年来似乎已经出现,这很复杂。 (显式NSThreads,NSOperationQueue,GCD等)

NSOperationQueue使用GCD ,所以如果使用GCD ,比直接使用GCD更容易。

使用GCD,并假定它比我更聪明的线程(重新)使用?

究竟。

我会使用NSOperationQueue或GCD和configuration文件。 无法想象线程开销会打败networking延迟。

NSOperationQueue会让你限制同时操作的数量,如果他们变得太贪心。 事实上,如果你需要的话,你可以把它限制为一个。