views:

331

answers:

2

So I'm trying to do all my REST calls that download data on the background thread so that the UI stays responsive.

I have a viewcontroller that contains a NSOperationQueue. I create an instance of my importer class that is a subclass of NSOperation. Inside the main() method of my importer, I am setting up a ASIHTTPDataRequest. I create the request, then its time to kick off the request.

Problem: I ran into a problem when starting the request by calling "startAsynchronous" on the request. The delegate call backs never get called. Its like the request starts, downloads its data, but never calls the delegate callback methods.

My solution: Everything seems to work fine (i.e. callbacks, etc) when I start the request synchronously. Is this the correct solution?

Why does the synchronous call work, but not the asynchronous? I'm modeling my importer class after Apples "TopSongs" sample.

A: 

When the method main() is end executing, NSOperation seted to finished and released, so you newer receive delegate callbacks because delegate is released.

jamapag
Outside of me using ASIHTTPRequest instead of NSURLConnection, the "TopSongs" samples does the same thing I am. It uses [[NSURLConnceciton alloc] initWithRequest:request delegate:self]; which is asynchronous as well, and it works fine. So it would seem to me that its something to do with ASIHTTPReqeust's startAsynchronous call.
Bryan
did you use code like this: do { [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; } while (!done);
jamapag
yes. I suspect something inside ASIHTTPRequest that is causing this issue. Debugging the asynchronous test I find that it never reaches the line after the "do...while" loop you listed above. Its like the code falling through the do/while statement and never executing any code below that.
Bryan
Moving discussion to http://groups.google.com/group/asihttprequest/browse_thread/thread/dc4aab8463fbe0e1/056868cdbf67394c#056868cdbf67394c
Bryan
+2  A: 

ASIHTTPRequest itself should not block the UI if you run it from the main thread.

  • ASIHTTPRequest isn't designed to be run from a background thread. [ASIHTTPRequest requestFinished] calls the "finished" callback on the main thread; it'll never be received by the background thread, so the background thread's run loop never runs.
  • ASIHTTPRequest is an NSOperation anyway. This is an implementation detail.
  • ASIHTTPRequest runs its network code in a background thread by default, so you're unlikely to see much benefit by sticking it in another thread.

If it's parsing the data that's taking a long time, stick that in an operation.

tc.
The main reason I moved the REST request call to my own NSOperation is because after the request is done, it will parse and saving into Core Data on that same background thread, keeping the UI responsive and allowing core data to be notified on the main thread its been updated and therefore updating my table on the main thread.
Bryan
So stick the parsing/saving into another thread, and coordinate stuff in the main thread.
tc.