NSThread与NSOperationQueue与???在iPhone上的比较

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 ++++++++++ 会再次创建子类

你可以对它们进行分析。那将是找出答案的一种方式。 - Alex Reynolds
性能并不是关键词,我怀疑它们在底层都是相同的。我更希望找到有两种或更多方法经验的人给我一些建议,告诉我哪种方法更好以及为什么更好。 - kubi
2个回答

33

总体而言,您可以使用NSOperationQueue获得更好的里程效益。

三个具体原因:

  • 您可能希望立即启动对许多项目的缓存。 NSOperationQueue足够聪明,只会创建与核心数量相近的线程,将其余操作排队。在使用NSThread时,创建100个线程以缓存100个图像可能过度且效率低下。
  • 您可能想取消cacheImage操作。使用NSOperationQueue实现取消操作更容易;大部分工作已经为您完成。
  • NSOperationQueue可以自由切换到更智能的实现(如Grand Central Dispatch),现在或将来都是如此。而NSThread则更有可能始终只是操作系统线程。

额外加分:

  • NSOperationQueue内置了其他一些不错的结构,例如一种尊重操作优先级和依赖性的复杂方式。

假设您不需要NSOperationQueue提供的额外功能,那么为什么创建100个NSThread是低效的呢?或者您是否认为如果需要创建100个线程,则必须需要一些NSOperationQueue好处? - Tony
4
@Tony: 创建线程非常昂贵。http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/CreatingThreads.html - kubi

5
我会使用NSOperationQueue。在OS 3.2下,NSOperationQueue在后台使用线程,因此这两种方法应该表现相似。但是,在Mac OS 10.6下,NSOperationQueue在后台使用GCD,因此不需要单独线程的开销。我没有查看OS 4的文档,但我认为它会做类似的事情-无论如何,NSOperationQueue可以交换实现方式,以便在iPhone上获得GCD的性能优势。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接