In my app I have an advanced search page which uses a tableview with 4 cells to access 4 tableviews as drop-down fields basically. These are populated from the results of parsing a xml I receive from a url request that happens when the app first loads and is stored in the appDelegate to be accessed by the tableviews later when the advanced search page is accessed. In normal, good internet connection circumstances, this takes a split-second, so the information is there far before the adv. search page could even be accessed, but I want to cover myself in case of a really slow connection. So, I am putting an alertview with a spinner over the advanced search page if a flag I set is false(the data is still being requested/parsed). I was able to get this to work, and I had the cancel button taking the user back to the previous page in case they didn't want to wait. But I also need the alert to be dismissed if the flag changes to true(meaning the parsing is done), and that is where I'm starting to have trouble. I'm starting an infinite loop to keep checking if the flag is true, and then dismissing the alert when it breaks out of it. I put it in a separate thread so the loop doesn't block the user from being able to hit the cancel button, but I'm getting all sorts of runtime errors about:
-[UIAlertView dismissWithClickedButtonIndex:animated:]: message sent to deallocated instance 0x105330
Here's the relevant code:
-(void)viewDidAppear:(BOOL)animated
{
[NSThread detachNewThreadSelector:@selector(waitTilDone) toTarget:self withObject:nil];
}
-(void)waitTilDone{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
while (mainDelegate.artistDone == @"no" || mainDelegate.mediumDone == @"no" || mainDelegate.seriesDone == @"no" || mainDelegate.areaDone == @"no") {
}
[av dismissWithClickedButtonIndex:0 animated:YES];
[pool release];
}
-(void)viewDidLoad
{
mainDelegate = (PublicArtOmahaAppDelegate*)[[UIApplication sharedApplication]delegate];
if (mainDelegate.artistDone == @"no" || mainDelegate.mediumDone == @"no" || mainDelegate.seriesDone == @"no" || mainDelegate.areaDone == @"no") {
av=[[UIAlertView alloc] initWithTitle:@"Loading Form Data" message:@"\n" delegate:sel开发者_StackOverflowf cancelButtonTitle:@"Cancel" otherButtonTitles:nil];
UIActivityIndicatorView *ActInd=[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
[ActInd startAnimating];
[ActInd setFrame:CGRectMake(125, 40, 37, 37)];
[av addSubview:ActInd];
[av show];
[av release];
}
[super viewDidLoad];
}
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
// the user clicked on the Cancel button
[self dismissModalViewControllerAnimated:YES];
}
So my questions are:
Is the infinite loop a crappy way of checking if I can dismiss it? I need to do it somehow... :/
Obviously I'm managing memory poorly here, but I'm pretty new to this so I don't know what I'm doing wrong. Is there a quick fix there?
For 1): Yes, that is crazy. Use key/value observing (KVO), [NSNotificationCenter defaultCenter]
, write your own delegate, or something else, to be notified when the value actually changes, instead of polling it.
For 2): Don't release it until you're done with it. Properties can be helpful here, since it simplifies a lot of things.
// In header
@property (nonatomic, retain) UIAlertView *av;
// When showing it
self.av = [[[UIAlertView alloc] initWith....] autorelease];
...
// When dismissing it
[self.av dismiss];
self.av = nil;
精彩评论