2010-11-08 88 views
2

UPDATE2我想我找到了泄漏的真正来源。我有一些业务对象具有我忘记发布的字符串属性。这些字符串属性是从我在此处创建的自定义xlm节点对象(KGYXMLNode)复制的。我不明白为什么会在此处报告泄漏,而不是我的自定义类。我的NSString属性是copy而不是retain为什么我的代码泄漏?

更新:我认为这是一个仪器或其他东西的bug,或者它不会再奇迹般地泄漏,但是因为xcode 4没有显示这个泄漏。

你好,根据仪器我有一个在下面的代码泄漏。我已经构建了一个围绕某些libxml函数的objective-c包装器,以便能够使用xpath解析xml文档,并且在此方法中,我为自定义节点对象设置了innerText。


-(void) SetInnerTextForNode: (xmlNodePtr) node : (KGYXMLNode *) obcNode 
{ 
    if ((node) && (node->children)) 
    { 
    for (xmlNodePtr pnode = node->children; pnode != NULL; pnode = pnode->next) 
    { 
     if (pnode->type == XML_TEXT_NODE) 
     { 
     xmlChar *content = pnode->content; 
     NSString *innerText = [[NSString alloc] initWithUTF8String: (char *)content]; 
     NSString *trimmedText = [innerText stringByTrimmingCharactersInSet: trimCharSet]; 
     if (trimmedText.length > 0) 
      obcNode.innerText = trimmedText; 
     [innerText release]; 
     break; 
     } 
    } 
    } 
} 

泄漏是NSString *innerText = [[NSString alloc] initWithUTF8String: (char *)content];。我不知道什么是错的。

回答

4

你不应该直接访问节点的内容,而是使用xmlNodeGetContent

        xmlChar *content = xmlNodeGetContent(pnode); 
        NSString *innerText = [[NSString alloc] initWithUTF8String: (char *)content]; 
        NSString *trimmedText = [innerText stringByTrimmingCharactersInSet: trimCharSet]; 
        if (trimmedText.length > 0) 
          obcNode.innerText = trimmedText; 
        [innerText release]; 
        // you must free what xmlNodeGetContent returns! 
        xmlFree(content); 
        break; 
2

我不知道为什么你的代码泄漏,但在我看来,你有一个不安全的赋值给obcNode.innerText的自动释放对象,而不保留它。

+2

是什么让你这么说?你怎么知道'innerText'属性是'assign','copy'还是'retain'? – 2010-11-08 14:21:41

+2

obcNode.innerText是一个复制属性。应该没问题。 – 2010-11-08 14:28:40

2

这是一个猜测,但我认为你的dealloc方法obcnode在释放时不释放它的innerText实例变量。乍一看,你的代码片段对于内存管理来说看起来很好,这是我能看到的唯一潜在的错误。

它会标记innerText泄漏的原因可能是trimmedText使用与innerText相同的底层unichar数组,但具有不同的开始和长度值,因此它保留innerText以阻止unichar数组消失。

因为trimmedText是一个不可变的字符串,发送副本只会导致它发送retain到自身并返回自己,所以obcNode拥有拥有innerText的trimmedText。

+0

我检查了innerText属性,它被释放。所以如果我释放我的innerText属性,它也应该释放trimmedText,然后释放原始的innertext。 – 2010-11-09 06:25:15

+0

我认为'[innerText stringByTrimmingCharactersInSet]'返回一个全新的字符串。我认为在我的情况下,内存中有3个不同的字符串,原始的'xmlChar * content'然后'NSString * innerText'被创建,然后是'NSString * trimmedText'。彼此独立。唯一对我很重要的对象是无限制的,因为它不是自动释放的。我想我不需要发布'xmlChar * content',但也许我错了。 – 2010-11-09 06:38:11

+0

有三个字符串,但可能不是三个底层的unichar数组。 – JeremyP 2010-11-09 08:59:22