2011-07-17 2 views
0

Я разбираю некоторые XML с помощью TouchXML, и я получаю crash -EXC_BAD_ACCESS. То, что я узнал из-за проб и ошибок, состояло в том, что если я не выпущу свой CXMLDocument (который я выделил), тогда все будет в порядке. Вот мой код:Weird crash, если я пытаюсь выпустить CXMLDocument

- (NSArray *)getLookUps { 

    //Do some stuff and then... 

    NSData *tempData = [NSURLConnection sendSynchronousRequest:request 
               returningResponse:nil 
                  error:nil]; 



     CXMLDocument *xmlDoc = [[CXMLDocument alloc] initWithData:tempData options:0 error:nil]; 
     NSDictionary *mappings = [NSDictionary dictionaryWithObject:@"http://****/****" 
                  forKey:@"****"]; 

     NSLog(@"%@", [[NSString alloc] initWithData:tempData encoding:NSUTF8StringEncoding]); 
     NSArray *orders = [[xmlDoc rootElement] nodesForXPath:@"//****:Unit" 
              namespaceMappings:mappings 
                 error:nil]; 

     NSMutableArray *units = [NSMutableArray arrayWithCapacity:200]; 

     for (CXMLElement *order in orders) { 
      NSArray *nodes = [order children]; 
      NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithCapacity:[nodes count]]; 

      for (CXMLElement *node in nodes) { 
       [dictionary setObject:[node stringValue] forKey:[node name]]; 
      } 
      [units addObject:dictionary]; 
     } 

     //[xmlDoc release]; 
    return units; 
} 

Посмотреть на 2-й последней строке [xmlDoc release]. Я прокомментировал это, потому что он падает, если я этого не делаю. Что я делаю не так? Благодарю.

+0

В какой-то момент вы не можете сохранить или перевыпускать что-то. Утечка CXMLDocument просто скрывает проблему. Что вы делаете с массивом, возвращаемым этим методом? Можете ли вы показать код, который вызывает этот метод? – albertamg

ответ

1

Возможно, вам необходимо сохранить словарь, иначе он также будет выпущен при выпуске анализатора. Попробуйте изменить [units addObject:dictionary]; на [units addObject:[dictionary retain]];.

Другая идея состоит в том, чтобы установить указатель на xmlDoc autorelease:

CXMLDocument *xmlDoc = [[[CXMLDocument alloc] initWithData:tempData options:0 error:nil] autorelease]; 
+0

Спасибо за ответ. Я изменил его на autorelease и его не сбой больше. Но я не понимаю, почему он сбой, когда я явно его выпускаю .... Если что-то еще нужно, он не должен его сохранить? У меня есть много других классов, которые используют почти тот же самый код, и они не авторекламы, но они не сбой. В любом случае, спасибо за вашу помощь/ – user635064

+1

Я верю, что 'arrayWithCapacity' и' dictionaryWithCapacity' создают объекты с автореализацией, поэтому они могут быть выпущены преждевременно, когда вы освобождаете xmlDoc. –

+0

Извините, если это вопрос о нобе, но что NSArray или NSDictionary имеют отношение к CXMLDocument? – user635064

1

Эта ошибка сообщили и помечается как зафиксировано в более новых версиях библиотеки.

http://code.google.com/p/touchcode/issues/detail?id=35

Я не проверял, чтобы увидеть, если это на самом деле фиксируется, комментарий по этому URL предполагает, что это не так.

На мой взгляд, этой библиотеки следует избегать вообще. Для IOS приложений, использование libxml2 по нескольким причинам:

  • Это проверенное и испытанное, насквозь
  • Это быстрый и эффективный
  • Построение на основе представления узла вашего XML может сделать его проще кодировать с, но он отнимает память, поскольку у вас всегда есть весь документ в памяти. У вас, вероятно, есть это несколько раз при разборе. Вместо этого вы должны разработать свой код для работы с подходом libxml2. Вы согласитесь, как только вы начнете разбирать документы значительного размера.
0

Я наблюдал в классе TouchXML «CXMLDocument», мы имеем следующую обработку в методе «dealloc».

- (void)dealloc 
{ 
    // Fix for #35 http://code.google.com/p/touchcode/issues/detail?id=35 -- clear up the node objects first (inside a pool so I _know_ they're cleared) and then freeing the document 

    @autoreleasepool { 

     nodePool = NULL; 

    } 
    // 
    xmlUnlinkNode(_node); 
    xmlFreeDoc((xmlDocPtr)_node); 
    _node = NULL; 
} 

Я не уверен, почему мы используем «autoreleasepool» в «dealloc». Это стандартное кодирование? Поправьте меня, если я ошибаюсь.

Смежные вопросы