2011-07-17 77 views
0

我解析一些XML使用TouchXML,我得到一個崩潰-EXC_BAD_ACCESS。我通過試驗和錯誤發現的是,如果我不釋放我的CXMLDocument(我分配),那麼一切都很好。以下是我的代碼:奇怪的崩潰,如果我試圖釋放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中,指針自動釋放:

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

感謝您的回覆。我改變它autorelease和它不崩潰了。但是我不明白爲什麼當我明確地釋放它時它會崩潰....如果其他東西需要它,它不應該保留它嗎?我有很多其他類使用幾乎完全相同的代碼,他們不autorelease,但他們不會崩潰。無論如何,感謝您的幫助/ – user635064

+1

我相信'arrayWithCapacity'和'dictionaryWithCapacity'創建自動釋放對象,以便在您釋放xmlDoc時可以提前釋放它們。 –

+0

對不起,如果這是一個noob問題,但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; 
} 

我不知道爲什麼我們在「dealloc」中使用「autoreleasepool」。這是標準編碼嗎?糾正我,如果我錯了。