views:

537

answers:

3

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;
}
A: 

Set the delegate of the XML parser to nil.

bpapa
nope, still executes both lines of code
nathanjosiah
A: 

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.

unforgiven
no because XMLParser is my NSObject. it is the delegate of my parser. NSXMLParser is the actual parser. the object "parser" has the delegate methods. i dont want "self" to handle the parsing"
nathanjosiah
i edited my code to show what i mean
nathanjosiah
+1  A: 

Hi

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

deanWombourne
...wow never thought of that, i dont know why i was thinking that it would stop the code from running... thank you though :)
nathanjosiah