ikevin8me
ikevin8me

Reputation: 4313

Are Objective-C blocks always executed in a separate thread?

Are Objective-C blocks always executed in a separate thread?

Specifically, I'm asking about the sendAsynchronousRequest:queue:completionHandler method of the NSURLConnection class. This is the scenario:

Main thread (1st thread) calls the sendAsynchronousRequest method the sendAsynchronousRequest is executed on a 2nd thread, managed by the NSOperationQueue when method is completed and calls commpletionHandler, which thread is it executed on? 2nd thread? yet another 3rd thread? or the 1st thread?

Thanks!

Upvotes: 8

Views: 5067

Answers (4)

user1775617
user1775617

Reputation: 71

A block is just a closure, like you have them in python or functional languages. They don't "run on a thread" they run where they are called.

int main(void)
{
    void (^f)(void) { printf("hello world!\n"); }
    f();
    return 0;
}

Does just what you think it does, no dispatch queues, no threads, no nothing.

Though, once you have blocks with all their nice capture semantics, it's very tempting to have APIs to schedule their execution everywhere. But basically, a block, is just the same as a function pointer and an ad-hoc struct containing all the variable captured, passed as an argument to the callback (it's even how it's implemented in the compiler).

Upvotes: 7

jrturton
jrturton

Reputation: 119242

Blocks are executed wherever they are told. Wrapping code in a block does not affect the thread or queue it will be run on. In your particular case, as documented, the completion block is executed on the queue that is passed in in the queue parameter.

I'm not sure, for your purposes, if you really need to distinguish between a queue and a thread, the key principle is that the URL request is performed asynchronously to the calling code, and the completion block is performed on the queue passed in as the method parameter.

Upvotes: 4

Dima
Dima

Reputation: 23624

As others have said, it will run on whatever queue you have specified. If this is a background queue, and you want to execute some code on the main thread, you can iclude a GCD block accessing the main queue. Your completion block would look something like this:

^(NSURLResponse *response, NSData *data, NSError*error){

   // do whatever in the background

   dispatch_async(dispatch_get_main_queue(), ^{
   // this block will run on the main thread
   });
}

Upvotes: 4

Jon Skeet
Jon Skeet

Reputation: 1500145

It executes it on whatever operation queue you specify as the queue argument:

Loads the data for a URL request and executes a handler block on an operation queue when the request completes or fails.

The queue parameter is documented as:

The operation queue to which the handler block is dispatched when the request completes or failed.

So it's really up to the NSOperationQueue exactly how many threads are used. I'd expect pooling behaviour - so while there can be multiple threads, I wouldn't expect a different thread per handler, necessarily.

Upvotes: 7

Related Questions