为什么我的代码泄露了?

时间:2010-11-08 13:39:47

标签: iphone objective-c memory-leaks instruments libxml2

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

更新:我认为这是仪器中的一个错误,或者它不再神奇地泄漏,但是因为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];。我不知道出了什么问题。

3 个答案:

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

答案 1 :(得分:2)

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

答案 2 :(得分:2)

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

为什么它会标记innerText的泄漏可能是trimmedText使用与innerText相同的底层unichar数组但具有不同的start和length值,因此它保留innerText以阻止unichar数组消失。

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