Search code examples
iosobjective-cmultithreadinggrand-central-dispatchnsrunloop

How does runLoop in GCD block work without source


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?


Solution

  • Every NSThread for properly working needs to be attached to runloop. When you call dispatch_async() GCD creates the thread with runloop which you would use with [NSRunLoop curentRunLoop]. When you create some work with NSURLConnection, as I understand, the created connection is attached to the current runloop as the source. So if you want that runloop would 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 receives 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