NSThreads、NSOperations 和 PerformSelector 之间的区别
我想问一些关于 iPhone 开发的简单但重要的问题。如果我们必须在后台执行任务,并且当后台任务完成时,我们将更新 UI,为此我们可以使用 NSThreads、NSOperations 或 (performSelector)performSelectorInBackgroundThread。所有这些之间有什么区别以及它们将如何影响我的应用程序性能。
还有一件事,下面写的这两个语句有什么区别:-
[self getData];
[self performSelector:@selector(getData)];
Please explain as i dont know the difference between all these things.
I want to ask some simple but important questions regarding iPhone development. If we have to perform tasks in the background and when the background tasks are completed we will update the UI, for this we can use NSThreads, NSOperations or (performSelector)performSelectorInBackgroundThread. What is the difference between all these and how they will effect my apps performance.
One more thing, what is the difference between these two statements written bellow:-
[self getData];
[self performSelector:@selector(getData)];
Please explain as i dont know the difference between all these things.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
之间实际上没有太大区别,
AND
唯一的区别是当您调用 [self getData] 时,编译器可以确定您要将 getData 消息发送到类
[self class]
的对象。如果它找不到任何先前声明的方法原型,则会出现警告。第一行和第二行将被转换为
当您想在运行时执行某些操作时(例如,您在运行时确定要发送给对象的确切消息),
performSelector:
,这确实很酷。或者这里是“现实生活”中的一个示例: UIButton 有方法因此它将操作存储在其内部的某个位置,并且当有适当的控制事件时它会调用:
NSOperation 只是用线程包装您的工作的好方法。 NSThread 只是 pthreads 的包装。
因此,您的应用程序性能并不真正取决于您使用线程的方式,但是使用 NSOperation 而不是 pthreads 更容易做到这一点。
There is actual not a big difference between
AND
The only difference is when you call [self getData] the compiler can determine that you want to send getData message to the object of class
[self class]
. And if it can't find any method prototypes, that were declared earlier there would be a warning.The first and the second lines would be translated to
performSelector:
is really cool thing when you want to do something at runtime (for example you determine at runtime what exact message you want to send to the object). Or here is an example from the "real life": UIButton has methodSo it stores the action somewhere in it's internals and when there is appropriate control event it calls:
NSOperation is just a nice way to wrap your work with threads. And NSThread is just wrapper to pthreads.
So your app performance doesn't really depend on the way you're using threads, however it's much easier to do that using NSOperation rather than pthreads.
NSThread 是 pthreads(POSIX 线程)的包装器。 pthreads 是在 Mach 线程之上实现的。使用 NSThread 时可以设置堆栈大小、优先级。 (顺便说一句,根据我的经验,堆栈大小根本不受影响。)
NSOperation/NSOperationQueue 是 Grand Central Dispatch (libdispatch) 又名 GCD 的包装器。 GCD 是在 pthread 之上实现的。对于许多任务来说,它们比 NSThread 更容易使用。它减少了任务队列、线程池管理等的样板代码。
PerformSelectorInBackground:调用 NSThread 并处理终止的 NSThread。对于仅调用一种方法来说,这是最容易使用的。
NSThread is wrapper for pthreads (POSIX threads). pthreads is implemented atop of Mach thread. You can set stack size, priority when you are using NSThread. (By the way, as far as my experience, stack size doesn't affect at all.)
NSOperation/NSOperationQueue is wrapper for Grand Central Dispatch (libdispatch) aka GCD. GCD is implemented atop of pthreads. These are more easily to use than NSThread for many tasks. It reduces boilerplate code for task queueing, thread pool managing and so forth.
performSelectorInBackground: invokes NSThread and treats terminated NSThread. It is the easiest to use in these for only one method invoking.
长话短说,大多数时候你不需要自己使用 NSThread,特别是如果你只使用 Objective-C,而且时间问题并不是那么重要。使用操作队列或调度队列实现行为。
NSOperation 是某个任务的包装器或封装。该任务可以定义为方法(NSInvocableOperation),或块(NSBlockOperation),或任何你想要的东西(通过子类化 NSOperation)。因此,您需要做的第一件事是以适当的方式包装您的工作(通常是在方法或块中)。
然后您将把该操作放入操作队列中。然后操作队列将尽快触发分离线程中的任务。
在iOS 4.0及更高版本中,您可以直接将块送入队列,而无需构建操作对象。您还可以使用不同类型的作业队列,称为调度队列。
PerformSelectorinBackgroundThread 与队列类似,因为它也为您创建一个线程并(有效)在该线程中运行一个方法。有时它可能很方便,但您仍然需要非常清楚将在分离线程上运行的任务单元。许多 Cocoa 方法都不是线程安全的,大多数 UIKit 操作需要在主线程上运行。
这导致了最后一个问题。您可以让分离的线程处理任务,但根据其结果更新 UI 应在主线程上运行。例如,您可以这样做
[aUIObject PerformSelectorOnMainThread:@selector(setMessage:) withData:...
To make a long story short, you need not work with NSThread yourself most of time, especially if you are working with Objective-C only, and the timing issue is not THAT critical. Implement the behavior using an operation queue or a dispatch queue.
NSOperation is a wrapper or an encapsulation of a certain task. The task could be defined as a method(NSInvocationOperation), or a block(NSBlockOperation), or anything you'd like (by subclassing NSOperation). So the first thing you need to do is to wrap your job in an appropriate way (in a method or a block typically).
Then you will put the operation into an operation queue. Then the operation queue will fire the task in a detached thread as soon as possible.
In iOS 4.0 and later, you can directly feed a block to the queue without building an operation object. Also you can use a different types of job queues, named dispatch queues.
performSelectorinBackgroundThread is similar to the queues as it also creates a thread for you and (effectively) run a method in that thread. It might be handy sometimes, but you still need to be very clear about the unit of tasks that will run on a detached thread. Many Cocoa methods are not thread-safe, and most UIKit operations need to run on the main thread.
That leads to the final concern. You may let detached threads work on the tasks, but updating UI according to their results should run on the main thread. For example, you can do like
[aUIObject performSelectorOnMainThread:@selector(setMessage:) withData:...