2012-03-12 108 views
3

在我的項目中實現使用XpathQuery時,我真的很難去除/避免泄漏。目前我正在使用libXml2.2.dylib進行解析。當我使用儀器檢查內存泄漏我在框架中發現了很多泄漏。 libXml2.2.dylib leaks listlibxml2.2.dylib創建大量內存泄漏

什麼是避免這些泄漏的解決方案。存儲器是我們更關心的問題,任何人都可以請我來修復/避免這些漏洞泄漏。提前感謝。

+0

您是否使用ARC?爲什麼不? – Moshe 2012-03-12 15:52:15

+0

我沒有使用ARC – ajay 2012-03-12 15:54:18

+0

@Moshe:它沒有幫助,libxml2是一個C庫。 – JeremyP 2012-03-12 15:56:09

回答

3

首先,如果內存是一個主要問題,那麼使用XML並不是您最好的解決方案。 JSON或二進制格式的內存效率更高。

其次,您的跟蹤不會在框架中顯示泄漏。顯示內容是由框架分配內存的泄漏對象。實際的泄漏更可能是在你的代碼中,通常是通過從庫中分配一個對象,但不釋放(或在這種情況下釋放)對象。看看堆棧痕跡。

+0

+1感謝您的方式,我同意我的錯誤。 – ajay 2012-03-13 03:27:59

1

我解決了這個問題。當我在文檔中有空標籤時,我得到了漏洞,我清楚地觀察並修改了一些代碼。基本上,我在我的XpathQuery.m中進行了糾正。

NSArray *PerformXPathQuery(xmlDocPtr doc, NSString *query) 
{ 
    xmlXPathContextPtr xpathCtx; 
    xmlXPathObjectPtr xpathObj; 
    /* Create xpath evaluation context */ 
    xpathCtx = xmlXPathNewContext(doc); 
    if(xpathCtx == NULL) 
    { 
     return nil; 
    } 
    /* Evaluate xpath expression */ 
    xpathObj = xmlXPathEvalExpression((xmlChar *)[query cStringUsingEncoding:NSUTF8StringEncoding], xpathCtx); 
    if(xpathObj == NULL) { 
     GLogInfo(@"%@",@"Unable to evaluate XPath"); 
     xmlXPathFreeObject(xpathObj); 
     xmlXPathFreeContext(xpathCtx); 
     return nil; 
    } 

    xmlNodeSetPtr nodes = xpathObj->nodesetval; 
    if (!nodes) 
    { 
     GLogInfo(@"%@",@"Nodes was nil."); 
     xmlXPathFreeObject(xpathObj); 
     xmlXPathFreeContext(xpathCtx); 
     return nil; 
    } 

    NSStringEncoding encoding = cocoaEncodingFromXmlEncodingConst(doc->encoding); 
    NSMutableArray *resultNodes = [NSMutableArray array]; 
    for (NSInteger i = 0; i < nodes->nodeNr; i++) 
    { 
     NSDictionary *nodeDictionary = DictionaryForNode(nodes->nodeTab[i], nil, encoding); 
     if (nodeDictionary) 
     { 
      [resultNodes addObject:nodeDictionary]; 
     } 
    } 

    /* Cleanup */ 
    xmlXPathFreeObject(xpathObj); 
    xmlXPathFreeContext(xpathCtx); 
    return resultNodes; 
} 

如果你使用相同的類,你可以絕對沒有任何懷疑地/ /想到內存泄漏使用這個方法。祝你好運。

+0

真正的問題是與 xmlChar * nodeContent = xmlNodeGetContent(currentNode); – Chandan 2016-05-29 19:01:38

0

如果你正在使用TFHpple那麼你需要添加以下代碼

DictionaryForNode

方法

給XPathQuery類

if (XML_ELEMENT_NODE != currentNode->type) { 
    return nil; 
} 

因此,您的最終方法應該看起來像

NSDictionary *DictionaryForNode(xmlNodePtr currentNode, NSMutableDictionary *parentResult,BOOL parentContent) 
{ 
NSMutableDictionary *resultForNode = [NSMutableDictionary dictionary]; 
if (currentNode->name) { 
    NSString *currentNodeContent = [NSString stringWithCString:(const char *)currentNode->name 
                 encoding:NSUTF8StringEncoding]; 
    resultForNode[@"nodeName"] = currentNodeContent; 
} 

if (XML_ELEMENT_NODE != currentNode->type) { 
    return nil; 
} 

xmlChar *nodeContent = xmlNodeGetContent(currentNode); 

if (nodeContent != NULL) { 
    NSString *currentNodeContent = [NSString stringWithCString:(const char *)nodeContent 
                 encoding:NSUTF8StringEncoding]; 
    if ([resultForNode[@"nodeName"] isEqual:@"text"] && parentResult) { 
     if (parentContent) { 
      NSCharacterSet *charactersToTrim = [NSCharacterSet whitespaceAndNewlineCharacterSet]; 
      parentResult[@"nodeContent"] = [currentNodeContent stringByTrimmingCharactersInSet:charactersToTrim]; 
      xmlFree(nodeContent); 
      return nil; 
     } 
     if (currentNodeContent != nil) { 
      resultForNode[@"nodeContent"] = currentNodeContent; 
     } 
     return resultForNode; 
    } else { 
     resultForNode[@"nodeContent"] = currentNodeContent; 
    } 
    xmlFree(nodeContent); 
} 

xmlAttr *attribute = currentNode->properties; 
if (attribute) { 
    NSMutableArray *attributeArray = [NSMutableArray array]; 
    while (attribute) { 
     NSMutableDictionary *attributeDictionary = [NSMutableDictionary dictionary]; 
     NSString *attributeName = [NSString stringWithCString:(const char *)attribute->name 
                encoding:NSUTF8StringEncoding]; 
     if (attributeName) { 
      attributeDictionary[@"attributeName"] = attributeName; 
     } 

     if (attribute->children) { 
      NSDictionary *childDictionary = DictionaryForNode(attribute->children, attributeDictionary, true); 
      if (childDictionary) { 
       attributeDictionary[@"attributeContent"] = childDictionary; 
      } 
     } 

     if ([attributeDictionary count] > 0) { 
      [attributeArray addObject:attributeDictionary]; 
     } 
     attribute = attribute->next; 
    } 

    if ([attributeArray count] > 0) { 
     resultForNode[@"nodeAttributeArray"] = attributeArray; 
    } 
} 

xmlNodePtr childNode = currentNode->children; 
if (childNode) { 
    NSMutableArray *childContentArray = [NSMutableArray array]; 
    while (childNode) { 
     NSDictionary *childDictionary = DictionaryForNode(childNode, resultForNode,false); 
     if (childDictionary) { 
      [childContentArray addObject:childDictionary]; 
     } 
     childNode = childNode->next; 
    } 
    if ([childContentArray count] > 0) { 
     resultForNode[@"nodeChildArray"] = childContentArray; 
    } 
} 

xmlBufferPtr buffer = xmlBufferCreate(); 
xmlNodeDump(buffer, currentNode->doc, currentNode, 0, 0); 
NSString *rawContent = [NSString stringWithCString:(const char *)buffer->content encoding:NSUTF8StringEncoding]; 
if (rawContent != nil) { 
    resultForNode[@"raw"] = rawContent; 
} 
xmlBufferFree(buffer); 
return resultForNode; 
}