从委托内调用abortParsing时NSXMLParser崩溃

问题描述:

我在NSOperation的主内部有一个NSXMLParser对象+委托。如果BOOL取消,NSXMLParser委托在执行每个回调之前进行检查;变量已设置。如果它被设置,它会调用[parser abortParsing]并立即返回。从委托内调用abortParsing时NSXMLParser崩溃

但是,会发生什么情况,只要返回执行,我的应用程序崩溃,非法内存访问。

这里是崩溃的调用堆栈:

#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:]() 

和当地人:

self MGTwitterHTTPURLConnection * 0x0 
_cmd SEL 0x518fbf0 

,你看到Twitter的东西与我的计算机运行的代码没有任何关系。这只是一个随机的内存崩溃。我不使用任何Twitter代码。 .m文件就在我的项目中并被编译。

这一块的委托方法之一代码:

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

这里,语法分析器创建并呼吁

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

    [parser parse]; 
    [parser release]; 
    parser = nil; 
    return resultTable; 
} 
  • 我在做什么错误的代码?
  • 有没有更好的停止NSXMLParser的方法?

感谢

通过运行[解析器abortParsing]你只能迫使[解析器来]功能停止。也许你正试图以后以任何方式访问数据?没有看到任何代码很难帮助你。

+0

在返回我自己的代码之前,它实际上崩溃了INSIDE NSXMLParser。让我看看能否在这里得到一个调用堆栈 –

+0

你确定它在[parser parse]函数中吗? –

+0

增加了崩溃的调用堆栈 –

好像你提供的解析被破坏的数据 - 也许已经释放

@Joris芒的NSXMLParser现在是线程安全的。但是,在给定的线程中它不是可重入的;请勿在另一个NSXMLParser的委托回调中对NSXMLParser调用-parse或-abortParsing。所以你有另一种方式调用这样的abortParsing方法...希望它可以帮助你!

- (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; 
} .....