奇怪的崩溃,如果我试图释放CXMLDocument

我正在使用TouchXMLparsing一些XML,我正在碰到-EXC_BAD_ACCESS。 我通过反复试验发现,如果我不释放我的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; } 

请参阅最后一行[xmlDoc release] 。 我已经评论说,如果我不这样做,就会崩溃。 我究竟做错了什么? 谢谢。

您可能需要保留字典对象,否则在释放parsing器时也会释放它。 尝试改变[units addObject:dictionary]; to [units addObject:[dictionary retain]];

另一个想法是将您的xmlDoc指针设置为autorelease:

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

这个错误被报告,并被标记为固定在较新版本的库中。

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

我没有testing过,看看它是否确实是固定的,那个url的评论暗示它不是。

在我看来,这个库应该完全避免。 对于iOS应用程序,使用libxml2有以下几个原因:

  • 它经过了彻底的testing和尝试
  • 这是快速和高效的
  • 构build基于节点的XML表示可能使代码更容易编写,但是由于您始终将整个文档存储在内存中,因此会浪费内存。 parsing时你可能不止一次。 您应该devise您的代码来使用libxml2方法。 一旦你开始parsing相当大的文件,你会同意的。

我经常使用TouchXML,还好(幸运的是)到目前为止我没有这个问题,但是刚刚发生…

我在这里发布了一个解决scheme: 内存崩溃使用[CXMLNode nodesForXPath]与命名空间映射

我在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; } 

我不知道为什么我们在“dealloc”中使用“autoreleasepool”。 这是标准的编码吗? 纠正我,如果我错了。