Question

what am i doing wrong? i cant get the xmlparser to stop parsing. i set a breakpoint on [xmlParser abortParsing]; and it gets run. but so does everything after if(success) here is my code:

-(void)viewDidLoad{

[NSThread detachNewThreadSelector:@selector(loadstuff)toTarget:self withObject:nil];

}

-(void)loadstuff{

 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];

 XMLParserdelegate *parserdeleagte = [[XMLParserdelegate alloc] init];
 [xmlParser setDelegate:parserdelegate];

 BOOL success = [xmlParser parse];

 if(success){
  NSLog(@"No Errors");

  links = [[NSMutableArray alloc] initWithArray:links];
  titles = [[NSMutableArray alloc] initWithArray:titles];
  dates = [[NSMutableArray alloc] initWithArray:dates];
  descriptions = [[NSMutableArray alloc] initWithArray:descriptions];

  loading = FALSE;
  [theTableView reloadData];
 }else{
  NSLog(@"Error parsing xml"); 
 }
 [pool release];
}

-(void)viewWillDisappear:(BOOL)animated{
 [super viewWillDisappear:animated];
 [xmlParser abortParsing];
 [xmlParser release];
 xmlParser = nil;
}
Was it helpful?

Solution

Calling [parser abortParsing] will certainly stop the parser but why would you expect it to stop the rest of your code - all you have done is ask the line [parser parse]; to end early - the parser may still return YES as it might have managed to parse successfully - it didn't run into an error, you asked it to stop!

As your parser is in a seperate thread you will have to tell that thread that you are no longer interested in the parser (in fact, you will have released the parser at this point so it may not exist anymore).

You will need to have another property in your object that your thread will check

@property (assign) BOOL cancelThread; // deliberate lack of nonatomic here!

Set this to be false before you detach your new thread :

- (void) viewDidLoad {
    self.cancelThread = NO;
    [NSThread detachNewThreadSelector:@selector(loadstuff)toTarget:self withObject:nil];
}

and then, inside your viewWillDisappear method, set it to be YES :

- (void) viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    self.cancelThread = YES;
    [xmlParser abortParsing];
    [xmlParser release];
    xmlParser = nil;
}

Finally, check this property in your thread to see if you need to end early i.e.

...
BOOL success = [xmlParser parse];

if (self.cancelThread) {
    [pool release];
    return;
}

if (success) {
    NSLog(@"No Errors");
    ...

Hope this helps,

Sam

OTHER TIPS

In your code snippet you are allocating two different parsers, in these two statements:

xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
XMLParser *parser = [[XMLParser alloc] init];

You should remove the second statement; morever, you need to change

[xmlParser setDelegate:parser];

to

[xmlParser setDelegate:self];

assuming your class also handles the parser's delegate methods, otherwise set it to nil.

Set the delegate of the XML parser to nil.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top