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:...