I'm no ASIHTTPRequest expert (NSURLRequest has always done me fine), but from a quick poke at the code, it looks like you'd use its delegate and didFinishSelector properties to give it someone to tell when the URL request is finished. So, for example:
- (void)startURLRequest
{
ASIHTTPRequest *myRequest;
/* code to set the request up with your target URL, etc here */
myRequest.delegate = self;
myRequest.didFinishSelector = @selector(HTTPRequestDidFinish:);
/* ... */
[myRequest startAsynchronous];
}
- (void)HTTPRequestDidFinish:(ASIHTTPRequest *)request
{
NSLog(@"Request %@ did finish, got data: %@", request, request.data);
[myTargetForData didReceiveData:request.data fromURL:request.originalURL];
}
Apple explicitly recommend that you use the built-in runloop style mechanisms for asynchronous HTTP fetching, not separate threads. Using separate threads is likely to result in worse performance — at least in terms of battery life and/or device heat, even if it's still fast enough.
That said, as a learning point, by far the quickest way to switch something onto a separate thread and have it report back to the main thread (remember: UIKit objects may be messaged only from the main thread) is by changing this:
- (void)postResult:(NSString *)result
{
instanceOfUILabel.text = result;
}
- (void)doExpensiveOperationOn:(NSString *)source
{
/* lots of expensive processing here, and then... */
[self postResult:result];
}
- (IBAction)userWantsOperationDone:(id)sender
{
[self doExpensiveOperationOn:@"some value or another"];
}
Into this:
- (void)postResult:(NSString *)result
{
instanceOfUILabel.text = result;
}
- (void)doExpensiveOperationOn:(NSString *)source
{
/* we're on a thread without an autorelease pool now, probably we'll want one */
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
/* lots of expensive processing here, and then... */
/* in this simplified example, we assume that ownership of 'result' is here on this thread, possibly on the autorelease pool, so wait until postResult has definitely finished before doing anything that might release result */
[self performSelectorOnMainThread:@selector(postResult:) withObject:result waitUntilDone:YES];
[pool release];
}
- (IBAction)userWantsOperationDone:(id)sender
{
[self performSelectorOnBackgroundThread:@selector(doExpensiveOperationOn:) withObject:@"some value or another"];
}
There's about a million possible concurrency errors you can make by just going threaded without thinking about it though, and in that example an obvious problem is that whatever triggered the IBAction can [probably] trigger it several more times before doExpensiveOperationOn has finished. Multithreading is not something to be dashed into lightly.