Сбой NSXMLParser при вызове abortParsing из делегата - PullRequest
0 голосов
/ 24 июля 2011

У меня есть объект NSXMLParser + делегат внутри основной части NSOperation. Делегат 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?

Спасибо

Ответы [ 3 ]

0 голосов
/ 09 октября 2012

Похоже, данные, которые вы предоставляете для разбора, повреждены - возможно, уже выпущены

0 голосов
/ 01 сентября 2014

@ Joris Mans NSXMLParser теперь безопасен для потоков.Тем не менее, он не реентерабелен в данном потоке;не вызывайте -parse или -abortParsing для NSXMLParser из обратного вызова делегата другого NSXMLParser.Таким образом, у вас есть другой способ вызова метода 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;
}  .....
0 голосов
/ 24 июля 2011

Запустив [parser abortParsing], вы только принудительно останавливаете функцию [parser parse].Может быть, вы пытаетесь получить доступ к данным каким-либо образом впоследствии?Трудно помочь вам, не увидев никакого кода.

...