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

发布于 2024-11-26 07:17:07 字数 1376 浏览 3 评论 0原文

我在 NSOperation 的 main 中有一个 NSXMLParser 对象+委托。 NSXMLParser 委托在执行每个回调之前检查 BOOL 是否取消;变量已设置。如果已设置,它将调用 [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?

谢谢

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

み青杉依旧 2024-12-03 07:17:07

通过运行 [parser abortParsing],您只会强制 [parser parse] 函数停止。也许您随后尝试以任何方式访问数据?如果没有看到任何代码,很难为您提供帮助。

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.

妳是的陽光 2024-12-03 07:17:07

似乎您提供的用于解析的数据已损坏 - 也许已经发布

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

百思不得你姐 2024-12-03 07:17:07

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

@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;
}  .....
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文