Thanks
Thanks

Reputation: 40329

How can I make a piece of code run in a separate thread?

I have a few method calls like this:

[self myFoo];
[self heavyStuff]; // this one in other thread
[self myBar];

which classes / methods do I have to look at? When I search for "thread", there comes a lot of classes, methods and functions. Which one's are most apropriate here?

Upvotes: 9

Views: 7352

Answers (5)

Frank Schmitt
Frank Schmitt

Reputation: 25766

If you're targeting Snow Leopard exclusively, you can use Grand Central Dispatch:

 [self myFoo];
 dispatch_async(dispatch_get_global_queue(0, 0), ^{
     [self heavyStuff];
     dispatch_async(dispatch_get_main_queue(), ^{
       [self myBar];
     });
 });

But it won't run on earlier systems (or the iPhone) and is probably overkill.

EDIT: it works on iPhone since iOS 4.x.

Upvotes: 8

Barry Wark
Barry Wark

Reputation: 107754

For "fire and forget", try [self performSelectorInBackground:@selector(heavyStuff) withObject:nil]. If you have more than one operation like this, you may want to check out NSOperation and its subclass NSInvocationOperation. NSOperationQueue managed thread pooling, number of concurrently executing operations and includes notifications or blocking methods to tell you when all operations complete:

[self myFoo];

NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self                                                                                                                                   selector:@selector(heavyStuff) object:nil];

[operationQueue addOperation:operation];
[operation release];

[self myBar];

...

[operationQueue waitUntilAllOperationsAreFinished]; //if you need to block until operations are finished

At a lower level, you can use use -[NSThread detachNewThreadSelector:@selector(heavyStuff) toTarget:self withObject:nil].

Upvotes: 15

Rob Napier
Rob Napier

Reputation: 299265

You've got lots of great pointers here, but don't forget to spend some time with the Threading Programming Guide. It provides good guidance not only on the technologies, but also good design of concurrent processing, and how to make better use of the run loop both with threads and instead of threads.

Upvotes: 7

Anh
Anh

Reputation: 6533

You could use NSOperationQueue and NSInvocationOperation:

[self myFoo];

NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self                                                                   selector:@selector(heavyStuff) object:nil];
[operationQueue addOperation:operation];

[self myBar];

Upvotes: 4

Marc W
Marc W

Reputation: 19241

You would do

[self performSelectorInBackground:@selector(heavyStuff) withObject:nil];

See the NSObject reference on Apple's site.

Upvotes: 19

Related Questions