4

I was trying to understand multithreaded programming in iOS.

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
               , ^{
                    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL   URLWithString:@"http://www.google.com"]];
                    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

                    if (connection == nil) {
                        NSLog(@"Request failed");

                    } else {
                        NSLog(@"Request sent");
                    }
                    [[NSRunLoop currentRunLoop] run];//How does this work?
                   });

This code works fine and I get callbacks as expected.

In the documentation https://developer.apple.com/library/ios/documentation/cocoa/Reference/Foundation/Classes/NSRunLoop_Class/Reference/Reference.html#//apple_ref/occ/instm/NSRunLoop/run

It is mentioned that 'run' method, 'Puts the receiver into a permanent loop, during which time it processes data from all attached input sources.'

Now, in above code, I didn't attach any source to the runLoop. How does it work?

optimus
  • 876
  • 1
  • 9
  • 19

1 Answers1

5

Every NSThread for properly working need to be attached to runloop. When you call dispatch_async() GCD create the thread with runloop which you would use with [NSRunLoop curentRunLoop]. When you create some work with NSURLConnection, as I understand, created connection is attached to current runloop as the source. So if you wan't that runloop will be alive and not to fall asleep, you need to perform [[NSRunLoop curentRunLoop] run]. In this case runloop will get the message when the connection receive it.

Hope this helps.

UPDATE:

By Apple documentation:

performSelector can be input source

Cocoa defines a custom input source that allows you to perform a selector on any thread.

that's why you need to perfom keep runloop alive:

When performing a selector on another thread, the target thread must have an active run loop

skyylex
  • 855
  • 1
  • 10
  • 24
  • Thanks. On further looking for answers, I found that every thread is created with a run loop and as per docs, in NSURLConnection, it schedules the connection on current runLoop. – optimus Jul 17 '14 at 08:07
  • 1
    @optimus I don't get it. I don't think this answered your question. What is the input source any way? – ljk321 Nov 12 '15 at 10:49
  • As per documentation in NSURLConnection.h, "An NSURLConnections created with the +connectionWithRequest:delegate: or -initWithRequest:delegate: methods are scheduled on the current runloop immediately, and it is not necessary to send the -start message to begin the resource load.

    ". This means, NSURLConnection is attaching an input source to the runloop. How exactly it is doing it (performSelector, custom Input source or something else) is some implementation detail that I didn't expect in the answer.

    – optimus Nov 12 '15 at 18:03