Reputation: 657
I wanted to clean up one of my projects and extracted parts of my source that I often reuse, in a single class. This class handles some requests to a web service, everything is fine so far ;). Until I extracted the code to its own class, I handled those requests with threads and callbacks in the calling class.
Now I have a "best practice" question:
In my code I do something like(simplified):
(void)foo{
Helper *h =[[Helper alloc]init];
[h doRequest];
}
doRequest performs a network action(in its own class)and I have to wait until this is request is finished. So I need a callback or something like this.
Should I simply thread doRequest incl. waituntildone=YES?
Do I have to thread the networking in the Helper class too? Or is it enough to call the method threaded something like this:
[NSThread detachNewThreadSelector:@selector(h doRequest) toTarget:self withObject:nil];
What is the best practice to get a callback from doRequest to the caller class after it has completed it’s tasks so that I can handle the returned values from the web service?
Thanks in advance.
Johannes
Upvotes: 0
Views: 4802
Reputation: 1777
I personally prefer calling performSelectorOnMainThread:withObject:waitUntilDone: at the end of any helper threads that need to send information back.
[self performSelectorOnMainThread:@selector(infoFromService:) withObject:aDictionaryWithInfo waitUntilDone:NO];
- (void)infoFromService:(NSDictionary *)aDictionary {
//Process all the information and update UI
}
Be sure to always use the main thread for any UI updates even if they happen in the middle of the worker thread, for example updating a count of how much information has been downloaded. Use the same technique to call the main thread with the relevant information.
Upvotes: 2
Reputation: 1682
Given doRequest does not return until the request is done you could do
- (void)fooCompletion:(void (^)(void))completion {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
Helper *h =[[Helper alloc]init];
[h doRequest];
if (completion) {
dispatch_async(dispatch_get_main_queue(), ^{
// doRequest is done
completion();
});
}
});
}
To call the method:
[self fooCompletion:^{
// do something after doRequest is done
}];
Upvotes: 3