0
votes

I have an NSXMLParser object+delegate inside the main of an NSOperation. The NSXMLParser delegate checks before executing each of its callbacks if a BOOL cancel; variable is set. If it is set it calls [parser abortParsing] and returns immediately.

What happens however is as soon as the return is executed my app crashes with an illegal memory access.

Here is the call stack for the crash:

#0  0x00080030 in -[MGTwitterHTTPURLConnection data] at .../Twitter/Twitter+OAuth/MGTwitterEngine/MGTwitterHTTPURLConnection.m:69
#1  0x35432808 in nodePush ()
#2  0x3543eb5a in xmlParseChunk ()
#3  0x3464ed64 in -[NSXMLParser parse] ()
#4  0x000510e2 in -[ItemTableParser parse:] ()

and the locals:

self    MGTwitterHTTPURLConnection *    0x0
_cmd    SEL 0x518fbf0

That Twitter stuff you see has NO relation whatsoever with the code I am running. It is just a random piece of memory where it crashes. I don't use any Twitter code whatsoever. The .m files are just there in my project and compiled.

Here a piece of code of one of the delegate methods:

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
    if ( self.cancel )
    {
        [parser abortParsing];
        return;
    }  .....

Here the code where the parser is created and called

-(NSArray *)parse:(NSData *)data
{
    NSXMLParser * parser = [[NSXMLParser alloc]initWithData:data];
    [parser setDelegate:self];

    [parser parse];
    [parser release];
    parser = nil;
    return resultTable;
}
  • What am I doing wrong?
  • Is there a better way of stopping an NSXMLParser?

Thanks

3

3 Answers

0
votes

By running [parser abortParsing] you only force the [parser parse] function to stop. Maybe you are trying to access the data in any way afterwards? It's hard to help you without seeing any code.

0
votes

Seems like the data you provide for parsing is corrupted - maybe is already released

0
votes

@Joris Mans NSXMLParser is now threadsafe. However, it is not reentrant on a given thread; don't call -parse or -abortParsing on an NSXMLParser from within a delegate callback of another NSXMLParser. So you have another way to call abortParsing method like this...Hope it helps you!

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict {
if ( self.cancel )
{
    dispatch_queue_t reentrantAvoidanceQueue = dispatch_queue_create("reentrantAvoidanceQueue", DISPATCH_QUEUE_SERIAL);
    dispatch_async(reentrantAvoidanceQueue, ^{
        [parser abortParsing];
    });
    dispatch_sync(reentrantAvoidanceQueue, ^{ });
    return;
}  .....