My timer isn't stopping my parsing
I want to put in a timeout in case it takes too long to find my location, send out the relevant url, and parse the xml. It worked when I used performSelector:withObject:afterDelay in the locationManager (just to test getting the xml), but when I put similar code around my parser it doesn't actually abort the parsing. I am testing this by dropping the delay to 0.01.
My problem is: even with the delay set to 0.01, it still waits for all the parsing to complete first, and only then does it put up the alertView that is coded in the parsingDidTimeout method.
I did try this with a timer, and that wasn't working as well as performSelector: does in the other parts of my code. Either way, it doesn't put up the alertView, and stop the parsing, until after the parsing has finished, no matter how long that takes.
I create a url which requires a radius. First I try a small radius, but if I don't get the data I need, I expand the radius and send the url again and parse again. Here is part of my StartParsing method.
xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
XMLParser *parser = [[XMLParser alloc] initXMLParser];
[xmlParser setDelegate:parser];
if (!hadToExpandRadius){//meaning, only do this the first time I send out the url and parse
[self performSelector:@selector(parsingDidTimeout:) withObject:nil afterDelay:0.01];
}
//Start parsing the XML file.
BOOL success = [xmlParser parse];
if(success){
if((didNotGetTheDataYet) && (radius < 500)){
hadToExpandRadius = YES;
radius = radius + 35;
[self startParsing];//do this same method, with larger radius
}
else {
NSLog(@"No Errors");
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(parsingDidTimeout:) object:nil];}
[parser release];
}
-(void)parsingDidTimeout{
[xmlParser abortParsing];
UIAlertView *servicesDisabledAlert = [[UIAlertView alloc] initWithTitle:@"Try Later" message:@"We need a better connection. We can get the data later." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[servicesDisabledAlert show];
[servicesDisable开发者_开发问答dAlert release];
[myActivityView stopAnimating];
}
Thank you for your help.
Calling performSelector:withObject:afterDelay:
you ask the run loop to call the selector later. But [xmlParser parse]
blocks the run loop, so it doesn't have a chance to call you selector.
abortParsing
is designed to be called inside parsers' delegate methods.
The workaround can be to parse in a separate thread.
Found it -- just extra ":" in my performSelector:@selector(parsingDidTimeout:)! I thought it was something fancy having to do with the second thread. Just syntax.
Thanks for explaining about the parse blocking the run loop. I was hoping not to need another thread, but your suggestion fixed my problem. Thanks.
精彩评论