Reputation: 10380
I am using NSURLConnection to make some http requests to my webservice, which returns a large text file. Obviously this blocks the main thread and adds lag, so I want to process this in the background. BTW, I realize that there are third party frameworks out there handle this particular job/situation, but I'm coding this myself because I need to learn about multithreading on iOS.
I can either detach an NSThread or pass the NSURLConnection code to GCD in a block. Both ways work fine initially (to make the http connection and send the request). The problem is how to get the data back from the server. Let me explain.... when my webservice sends the data back, my app is informed via callbacks from the NSURLConnectionDelegate protocol. But by the time this happens, either my detached thread has exited it's target method, or the block has already been processed by GCD an it's off the queue (depending on which of the approaches I have used). Basically, the callback goes unnoticed by my app (unless of course I'm using dispatch_main_queue).
What is the "correct" objective-c way to solve this with each case?
Thanks for any direction
Upvotes: 0
Views: 394
Reputation: 56625
For networking code I would use the asynchronous method on NSULRConnection and process the data I get back on a background queue. Only the data that modifies the UI and needs to be on the main queue would be dispatched (using GCD) to the main queue.
NSOperationQueue *yourQueue = [[NSOperationQueue alloc] init];
[NSULRConnection sendAsynchronousRequest:yourRequest
queue:yourQueue
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
// The code inside here gets processed once the url request completes ...
// It happens in the background on "yourQueue".
[self doSomeExpensiveDataProcessingWithData:data];
dispatch_sync(dispatch_get_main_queue(), ^{
// Update UI on the main thread and wait to continue processing the data
[self updateUI];
});
[self doSomeMoreDataProcessing];
dispatch_sync(dispatch_get_main_queue(), ^{
// Update UI on the main thread and wait to continue processing the data
[self finalUpdateOfUI];
});
}];
Outside the example of networking code I generally like asynchronous callbacks as a design pattern. It becomes easy to test different callbacks in isolation and it divides the different callbacks (like error handling and data processing) into different methods which gives more focused code inside those methods.
GCD is very good for quickly doing a few lines of code on another thread or dispatching some work asynchronously.
NSThread is rarely used anymore.
Upvotes: 2
Reputation: 21229
Sounds like a NSRunLoop problem ... Read this for example ...
http://www.sortedbits.com/nsurlconnection-in-its-own-thread/ http://www.cocoaintheshell.com/2011/04/nsurlconnection-synchronous-asynchronous/
... Google for more ...
... why do you want to do it in this way? It's enough to use NSURLConnection asynchronously as it is (on main thread) and then dispatch your heavy processing of these data when they're received. In other words, NSURLConnection delegate methods will be called on the main thread, but then dispatch data processing only to not block main thread.
Upvotes: 0