xcoder
xcoder

Reputation: 967

How to write a non-blocking method in objective-c

I want to write a method that does not block. The method doesn't return anything. This is not over the web or anything - its all local to the device it is running on.

Basically, the calling method just wants some other object to take care of something. And once it tells it "Go do this", the caller wants to get back to doing its own work instead of waiting for the object to finish executing the task.

I don't want to use NSNotification.

EDIT: I want to be able to do this using frameworks available on iOS 3.1.2 and later

EDIT: Thanks for all the great replies - but I am unsure about which to choose. My requirements are simply that the calling method be able to send arguments to the called method, and return immediately without waiting for the result. Which would be the best solution?

Upvotes: 2

Views: 2001

Answers (5)

Oliver Pearmain
Oliver Pearmain

Reputation: 20590

This little peach worked for me (in-order to delay for 20 seconds)....

CFRunLoopRunInMode(kCFRunLoopDefaultMode, 20.0, false);

Upvotes: 0

justin
justin

Reputation: 104698

You use one of: libdispatch, NSOperation, add an NSInvocation or 'perform selector on thread' to a run loop, create a thread...

Update

It depends on the time and complexity of what you want to do. If it's rather simple (e.g. simple text parsing), then just add it to the main run loop. If it takes more time (e.g. a download or opening a file), then you will want it off the main run loop.

Create a thread

You can use pthreads interfaces to create one or more threads to perform your work.

One might choose pthreads for the greatest performance and control of any option in the list. Regarding performance: It requires that you will understand costs and the problems well. Creating threads is not trivial, so it's good to reuse them or divide tasks well. Making and testing concurrent designs also takes a good amount of time.

Personally, I use a more portable abstraction (over pthreads, specifically) for most of my multithreading needs. If portability is important, then you'll likely want to use such an abstraction layer because the remainder of the options are not really seen outside of Apple's systems.

You could also use something like -[NSObject performSelectorInBackground:withObject:] for convenience with objc types.

libdispatch

(a.k.a. GCD)

Although I read it not an option for you, I'll write a brief overview regardless: Can be likened to a task/scheduler/thread pool abstraction layer over pthreads. This library is often used for concurrent tasks. It uses thread pooling for tasks, which may block or run asynchronously. Rather fast and simple abstraction, and easy to use.

NSOperation

Task (NSOperation) / pool+scheduler (NSOperationQueue) based interface which now uses libdispatch. This feels more task focused than libdispatch. It preceded libdispatch, and has an ObjC interface. There is, however, a lot of overlap in functionality. Rather fast and simple abstraction, and easy to use.

Add an NSInvocation or 'perform selector on thread' to a run loop

If your task is simple, you may want to use this low overhead approach of simply telling an object to perform a selector or an NSInvocation on a particular thread. The system will add it to the list of things to do (for the specified thread's run loop).

Having read your updates and comments and not knowing the time/complexity your specific problem, I'd suggest NSOperation. pthreads are pretty complex, and you should favor pooling over spawning threads whenever you need something to be performed asynchronously.

Upvotes: 2

dasdom
dasdom

Reputation: 14063

I would use GCD.

Upvotes: 2

deanWombourne
deanWombourne

Reputation: 38475

There's a few useful methods on NSObject that can help you - this one probably the most :

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


- (void)doStuff {
    // Do whatever you want to do here. It's in the background.
}

However, that assumes that you don't want to cancel your background task - you should also look at NSOperation and NSOperationQueue if you need more control.

Upvotes: 2

tobiasbayer
tobiasbayer

Reputation: 10379

Use NSThread's detachNewThreadSelector:toTarget:withObject:.

Upvotes: 1

Related Questions