views:

620

answers:

2

I have a few tabs in my iPhone application which take a few seconds to load (pulling large amounts of data from a local sqlite database). When the users touch the tabs it appears as if the application is doing absolutely nothing. I've attempted to put a window showing a spinner up, however it is never shown due to the fact that the processing immediately follows.

I know i have a couple of different options for loading the data asynchronously, however i wanted to poll the community and see if there were any potential problems with just forcing another cycle of the NSRunloop to show the window.

Here's what my code looks like...

[[ActivityIndicator sharedActivityIndicator] show];
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate date]];

On a scale of 1 to 10 how bad would you rate this hack?

+2  A: 

I don't know where I'd rate it, but I know I wouldn't want to do it that way. Messing with the system default runloop just seems like a bad idea.

There are a couple of what I think are good approaches. The simplest is to put the additional processing in a separate private method, and then do this:

[[ActivityIndicator sharedActivityIndicator] show];
[self performSelector:@selector(processingMethod) withObject:nil afterDelay:0];

That will cause processingMethod to be called at the end of the run loop, after your indicator is showing. Should work fine.

The one caveat is that if your indicator is animated, depending on how it's set up it may not be animated while processingMethod is running. In that case you'd want to run processingMethod in a background thread, which might be a little more complicated, or might be as simple as doing this instead:

[self performSelectorInBackground:@selector(processingMethod) withObject:nil];

The potential complication there is that at the end of processingMethod, when you're going to display the results of your processing, you may have to call a method back onto the main thread.

Jack Nutting
I agree with Jack and I think that Lounges is looking for his second answer "performSelectorInBackground" -- with callback.
mobibob
+1  A: 

My experience is that the event handling code on iPhone is not reentrant. So if you're running the runloop in default mode be prepared for various crashes. I've found others are having issue too:

  1. http://lists.apple.com/archives/xcode-users/2009/Apr/msg00313.html
  2. http://www.iphonedevsdk.com/forum/iphone-sdk-development-advanced-discussion/16246-trying-make-modal-dialog-using-nested-nsrunloop.html
mfazekas
You are correct, and furthermore, Apple's doc states that the thread is not reentrant. You should not access data of other threads. The call back -- and 'give the data' -- is the preferred approach.
mobibob