96

What is the best way to run code on a separate thread? Is it:

[NSThread detachNewThreadSelector: @selector(doStuff) toTarget:self withObject:NULL];

Or:

    NSOperationQueue *queue = [NSOperationQueue new];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
                                                                        selector:@selector(doStuff:)
                                                                          object:nil;
[queue addOperation:operation];
[operation release];
[queue release];

I've been doing the second way but the Wesley Cookbook I've been reading uses the first.

Mike S
  • 3,994
  • 5
  • 31
  • 66

4 Answers4

244

In my opinion, the best way is with libdispatch, aka Grand Central Dispatch (GCD). It limits you to iOS 4 and greater, but it's just so simple and easy to use. The code to do some processing on a background thread and then do something with the results in the main run loop is incredibly easy and compact:

dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // Add code here to do background processing
    //
    //
    dispatch_async( dispatch_get_main_queue(), ^{
        // Add code here to update the UI/send notifications based on the
        // results of the background processing
    });
});

If you haven't done so already, check out the videos from WWDC 2010 on libdispatch/GCD/blocks.

Jacques
  • 6,030
  • 1
  • 29
  • 24
  • I need it to be 3.0 compatible :( – Mike S Oct 06 '10 at 04:03
  • 1
    Then operation queues are probably the next-best solution. Also, make sure you aren't diving into concurrency too quickly. Try starting by writing things single-threaded and profile to see if you need to go multithreaded, or if you can design your single-threaded code to be more efficient on its own. For simple tasks, you can sometimes do everything you need with performSelector:withObject:afterDelay: and avoid all of the issues that come with multi-threaded programming. – Jacques Oct 06 '10 at 04:15
  • Sorry for resurrecting this so much later, but if I spawn a method call with performSelector:withObject:afterDelay do I still need to use an NSAutoReleasePool inside the async method? If it magically uses the main auto release pool then the performSElector:afterDelay is definitely a quicker option. – Mike S Mar 02 '11 at 06:48
  • No, because the method is being run on the main thread, which has its own autorelease pool. – Jacques Mar 04 '11 at 23:06
  • i just recently came across this and was wondering how i could kill these background threads if need be? is there something like: myThread = displatch_async(...). myThread.kill()? – Joe Jan 28 '12 at 23:01
  • 4
    @Joe At the risk of saying something you already know, you should not get in the habit of writing code that kills threads, it will not help you or your career in the long run. See [this post](http://stackoverflow.com/questions/4149146/why-and-when-shouldnt-i-kill-a-thread) (or many like it) for reasons why not to kill threads. – MikeC Mar 18 '12 at 05:56
  • Is this a good technique to use to spawn a run-loop that listens on an asynchronous CFSocket? – Eduardo Aug 03 '12 at 12:16
  • if Suppose i want to stop back ground execution in the middle, what is the way? – siva Dec 13 '14 at 05:48
  • I got crash becuse i used `QOS_CLASS_BACKGROUND `, which is written in the docs. And it is specified above that line, that you can use other values like `DISPATCH_QUEUE_PRIORITY_DEFAULT `. I was in a hurry i didnt pay attention. Thats how i got to this question. – Martin Berger Jun 29 '15 at 14:25
1

The best way for the multithreading in iOS is using GCD (Grand Central Dispatch).

//creates a queue.

dispatch_queue_t myQueue = dispatch_queue_create("unique_queue_name", NULL);

dispatch_async(myQueue, ^{
    //stuffs to do in background thread
    dispatch_async(dispatch_get_main_queue(), ^{
    //stuffs to do in foreground thread, mostly UI updates
    });
});
Serge Ballesta
  • 121,548
  • 10
  • 94
  • 199
Kusal Shrestha
  • 641
  • 5
  • 14
0

I would try all the techniques people have posted and see which is the fastest, but I think this is the best way to do it.

[self performSelectorInBackground:@selector(BackgroundMethod) withObject:nil];
Bobby
  • 5,406
  • 3
  • 30
  • 35
0

I have added a category on NSThread that will let you execute threads in blocks with ease. You can copy the code from here.

https://medium.com/@umairhassanbaig/ios-how-to-perform-a-background-thread-and-main-thread-with-ease-11f5138ba380

Umair
  • 956
  • 9
  • 11