Reputation: 876
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?
Upvotes: 4
Views: 2737
Reputation: 815
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
Upvotes: 5