从委托内部调用abortParsing时NSXMLParser崩溃

时间:2011-07-24 10:33:41

标签: iphone cocoa nsxmlparser nsoperation

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

但是,一旦执行返回,我的应用程序就会因非法内存访问而崩溃。

这是崩溃的调用堆栈:

#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?

由于

3 个答案:

答案 0 :(得分:0)

通过运行[parser abortParsing],你只能强制[parser parse]函数停止。也许你之后试图以任何方式访问数据?如果没有看到任何代码,很难帮助你。

答案 1 :(得分:0)

似乎您为解析提供的数据已损坏 - 可能已经发布

答案 2 :(得分:0)

@Joris Mans 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;
}  .....