iOS8 NSXMLParser崩溃

Cri*_*one 6 nsxmlparser ios8

我在NSXMLParser中崩溃了

*因未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因是:'NSXMLParser不支持可重入解析.'

这是我的代码

NSString *wrappedSnippet = [NSString stringWithFormat:@"<html>%@</html>", self.snippet];
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:[wrappedSnippet dataUsingEncoding:NSUTF8StringEncoding]];
[parser setDelegate:self];
[parser parse];
Run Code Online (Sandbox Code Playgroud)

应用程序在最后一行崩溃.

请注意,iOS7上的一切都很完美!

bnd*_*ati 9

iOS8抛出了一个异常,即以前的版本在后台捕获和处理.
请参阅手册从ios 5 NSXMLParser是线程安全但不可重入!确保您没有从NSXMLParser委托调用解析.在你的情况下"自我".

  • 你是对的.我的问题的本质是我创建另一个NSXMLParser实例并在另一个的回调堆栈中调用parse.谢谢! (3认同)

Ami*_* C. 7

dispatch_queue_t reentrantAvoidanceQueue = dispatch_queue_create("reentrantAvoidanceQueue", DISPATCH_QUEUE_SERIAL);
    dispatch_async(reentrantAvoidanceQueue, ^{
        NSXMLParser* parser = [[NSXMLParser alloc] initWithData:xml];
        [parser setDelegate:self];
        if (![parser parse]) {
            NSLog(@"There was an error=%@ parsing the xml. with data %@", [parser parserError], [[NSString alloc] initWithData:xml encoding: NSASCIIStringEncoding]);
        }
        [parser release];
    });
    dispatch_sync(reentrantAvoidanceQueue, ^{ });
Run Code Online (Sandbox Code Playgroud)

用上面的代码替换你的代码,希望它对你有所帮助!


Cri*_*one 6

我通过在后台队列中调度解析器来解决我的问题!

NSXMLParser现在是线程安全的.但是,它在给定的线程上不可重入; 不要在另一个NSXMLParser的委托回调中调用NSXMLParser上的-parse.

- (void)parseWithCompletion:(ParserHandler)handler {
     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
     dispatch_async(queue, ^{
          self.handler = handler;
          [self parse];
     });
}

- (void)parserDidEndDocument:(NSXMLParser *)parser {
     dispatch_async(dispatch_get_main_queue(), ^{
          if (self.handler) {
             self.handler(YES, self.dictionary, nil);
             self.handler = nil;
          }
     });
}
Run Code Online (Sandbox Code Playgroud)