NSThread vs. NSOperationQueue vs. ???在 iPhone 上
目前我正在使用 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
吗?当它针对 iPhone 发布时,GCD 是第四个选项,但除非有显着的性能提升,否则我宁愿坚持适用于大多数平台的方法。
根据 @Jon-Eric 的建议,我采用了 NSOperationQueue
/NSOperation
子类解决方案。它运作得很好。 NSOperation 类非常灵活,您可以根据需要将其与调用、块或自定义子类一起使用。无论您如何创建 NSOperation,当您准备好运行它时,您都可以将其放入操作队列中。这些操作被设计为既可以作为放入队列的对象来工作,也可以根据需要将它们作为独立的异步方法运行。由于您可以轻松地同步运行自定义操作方法,因此测试非常简单。
自从我提出这个问题以来,我在几个项目中使用了同样的技术,我对它保持我的代码和测试干净、有组织和异步的方式感到非常满意。
一个++++++++++ 会再次子类化
Currently I'm using NSThread
to cache images in another thread.
[NSThread detachNewThreadSelector:@selector(cacheImage:) toTarget:self withObject:image];
Alternately:
[self performSelectorInBackground:@selector(cacheImage:) withObject:image];
Alternately, I can use an NSOperationQueue
NSInvocationOperation *invOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(cacheImage:) object:image];
NSOperationQueue *opQueue = [[NSOperationQueue alloc] init];
[opQueue addOperation:invOperation];
Is there any reason to switch away from NSThread
? GCD is a 4th option when it's released for the iPhone, but unless there's a significant performance gain, I'd rather stick with methods that work in most platforms.
Based on @Jon-Eric's advice, I went with an NSOperationQueue
/NSOperation
subclass solution. It works very well. The NSOperation
class is flexible enough that you can use it with invocations, blocks or custom subclasses, depending on your needs. No matter how you create your NSOperation
you can just throw it into an operation queue when you are ready to run it. The operations are designed to work as either objects you put into a queue or you can run them as standalone asynchronous methods, if you want. Since you can easily run your custom operation methods synchronously, testing is trivially easy.
I've used this same technique in a handful of projects since I asked this question and I couldn't be happier with the way it keeps my code and my tests clean, organized and happily asynchronous.
A++++++++++
Would subclass again
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
一般来说,使用 NSOperationQueue 会获得更好的效果。
三个具体原因:
NSOperationQueue
足够智能,只创建与核心数量相同的线程,并对剩余的操作进行排队。使用 NSThread,创建 100 个线程来缓存 100 个图像可能有点矫枉过正,而且效率有些低下。cacheImage
操作。使用 NSOperationQueue 实现取消更容易;大部分工作已经为您完成。NSOperationQueue
现在或将来可以自由切换到更智能的实现(例如 Grand Central Dispatch)。NSThread
更有可能始终只是一个操作系统线程。额外的好处:
In general you'll get better mileage with
NSOperationQueue
.Three specific reasons:
NSOperationQueue
is smart enough to only create about as many threads as there are cores, queuing the remaining operations. WithNSThread
, creating 100 threads to cache 100 images is probably overkill and somewhat inefficient.cacheImage
operation. Implementing cancellation is easier withNSOperationQueue
; most the work is already done for you.NSOperationQueue
is free to switch to a smarter implementation (like Grand Central Dispatch) now or in the future.NSThread
is more likely to always be just an operating system thread.Bonus:
NSOperationQueue
has some other nice constructs built-in, such as a sophisticated way of honoring operation priorities and dependencies.我会使用 NSOperationQueue。在 OS 3.2 下,
NSOperationQueue
在底层使用线程,因此这两种方法应该执行类似的操作。然而,在 Mac OS 10.6 下,NSOperationQueue
在底层使用 GCD,因此具有没有单独线程开销的优点。我还没有看过 OS 4 的文档,但我怀疑它做了类似的事情——无论如何,如果/当 GCD 的性能优势可用于 OS 4 时,NSOperationQueue
可以交换实现。 iPhone。I would use
NSOperationQueue
. Under OS 3.2,NSOperationQueue
uses threads under the hood, so the two methods should perform similarly. However, under Mac OS 10.6,NSOperationQueue
uses GCD under the hood and so has the advantage of not having the overhead of separate threads. I haven't looked at the docs for OS 4, but I'd suspect it does something similar--in any case,NSOperationQueue
could swap implementations if/when the performance advantages of GCD become available for the iPhone.