30

目前我正在使用NSThread在另一个线程中缓存图像。

[NSThread detachNewThreadSelector:@selector(cacheImage:) toTarget:self withObject:image];

交替:

[self performSelectorInBackground:@selector(cacheImage:) withObject:image];

或者,我可以使用NSOperationQueue

NSInvocationOperation *invOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(cacheImage:) object:image];
NSOperationQueue *opQueue = [[NSOperationQueue alloc] init];
[opQueue addOperation:invOperation];

有什么理由放弃NSThread吗?GCD 是为 iPhone 发布的第四个选项,但除非有显着的性能提升,否则我宁愿坚持在大多数平台上都可以使用的方法。


根据@Jon-Eric 的建议,我采用了NSOperationQueue/NSOperation子类解决方案。它工作得很好。该类NSOperation足够灵活,您可以根据需要将其与调用、块或自定义子类一起使用。无论您如何创建您的NSOperation,您都可以在准备好运行它时将其放入操作队列中。这些操作既可以作为放入队列的对象,也可以作为独立的异步方法运行,如果需要的话。由于您可以轻松地同步运行自定义操作方法,因此测试非常容易。

自从我提出这个问题以来,我已经在几个项目中使用了同样的技术,我对它保持我的代码和测试干净、有条理和愉快的异步方式感到非常满意。

A++++++++++++ 将再次子类化

4

2 回答 2

33

一般来说,您将获得更好的里程数NSOperationQueue

三个具体原因:

  • 您可能希望一次启动多个项目的缓存。NSOperationQueue足够聪明,只创建与内核一样多的线程,将剩余的操作排队。使用NSThread,创建 100 个线程来缓存 100 个图像可能是矫枉过正且效率低下。
  • 您可能想取消该cacheImage操作。NSOperationQueue使用;实现取消更容易 大多数工作已经为您完成。
  • NSOperationQueue现在或将来可以自由切换到更智能的实现(如 Grand Central Dispatch)。NSThread更有可能始终只是一个操作系统线程。

奖金:

  • NSOperationQueue内置了一些其他不错的构造,例如尊重操作优先级和依赖关系的复杂方法。
于 2010-06-15T02:36:18.553 回答
5

我会用NSOperationQueue. 在 OS 3.2NSOperationQueue下,在后台使用线程,因此这两种方法的执行方式应该相似。但是,在 Mac OS 10.6NSOperationQueue下,在底层使用 GCD,因此具有没有单独线程开销的优势。我没有查看 OS 4 的文档,但我怀疑它会做类似的事情——无论如何,NSOperationQueue如果/当 GCD 的性能优势可用于 iPhone 时,可以交换实现。

于 2010-06-15T02:22:24.450 回答