libxml2.2.dylib创建了大量内存泄漏

时间:2012-03-12 15:48:24

标签: iphone objective-c ios xml-parsing libxml2

在我的项目中实现使用 XpathQuery 时,我很难删除/避免泄漏。目前我使用libXml2.2.dylib进行解析。当我检查内存泄漏时使用工具我在框架中发现了很多泄漏。libXml2.2.dylib leaks list

什么是避免这些泄漏的解决方案。记忆是我们更关心的问题,任何人都可以请我解决/避免这些错误的泄漏。谢谢提前。

3 个答案:

答案 0 :(得分:3)

首先,如果内存是一个主要问题,那么使用XML并不是最好的解决方案。 JSON或二进制格式的内存效率更高。

其次,您的跟踪不会在框架中显示泄漏。显示的是泄漏的对象,其内存由框架分配。实际泄漏更可能是在您的代码中,通常是通过从库中分配对象,但不释放(或在这种情况下释放)对象。查看堆栈跟踪。

答案 1 :(得分: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;
}

如果您使用相同的类,您可以毫无疑问地使用此方法/思考内存泄漏。祝你好运。

答案 2 :(得分:0)

如果您使用TFHpple,则需要在

中添加以下代码
  

DictionaryForNode

的方法
  

XPathQuery类

extension Array {
func accumulate<U>(initial: U, combine: (U, Element) -> U) -> [U] {
    var running = initial
    return self.map { next in
        running = combine(running, next)
        return running
        }
    }
}

let test = [1,2,3,4]
test.accumulate(0, combine: +)
// returns [1, 3, 6, 10]

所以你的最终方法看起来应该是

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