0

我使用 NSXMLParser 来解析 XML 文档。我有以下功能(除其他外):

- (void) parserDidStartDocument:(NSXMLParser *)parser {

    // Init tempString
    tempString = [NSMutableString string];

}    
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {

        // save gained data for element "date"
        if ([elementName isEqualToString:@"date"])
            [entryDict setObject:[tempString copy] forKey:kXMLDictDateKey];

        [tempString setString:@""];
    }


    //
    // Character Handling
    //
    - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
        [tempString appendString:[[XMLParser alloc] stripUnwantedStringChars:string]]; //Just strips tabs and linebreaks and the returns the string
    }

tempString 是具有以下属性的实例变量:

@property (nonatomic, retain) NSMutableString *tempString;

tempString 不必在 dealloc 中释放,因为它是使用便利方法启动的,因此它会自动分配给自动释放池。我还使用 alloc、init 方法尝试了以下方法,但结果相同。所以这就是我所做的:

1.)用仪器运行我的项目,让它在启动后立即搜索泄漏,没有。2.) 运行一次 XML 解析器,检查是否有泄漏。没有了。3.) 再次运行 XML Parser,现在突然出现[entryDict setObject:[tempString copy] forKey:kXMLDictDateKey];泄漏。

我已经研究这些内存泄漏几个小时了,我忘记了什么?如果您需要更多代码,请告诉我,尽管我认为我的问题出在这些行中。

附言。我的检查显示在解析器(委托)调用之间调用了“dealloc”方法,因此我认为解析器实际上被加载了两次,而不仅仅是一次。

4

4 回答 4

3

您致电:

tempString = [NSMutableString string];

实际上不调用属性(包装器)和retain.

你应该这样做:

self.tempString = [NSMutableString string];

否则,您只是将 ivar 直接设置为自动释放的对象。

您不仅在某处有泄漏,上述代码有时还会导致一些有趣的崩溃。

于 2010-01-30T23:58:50.097 回答
1

您的代码中的另一个错误是:

[tempString appendString:[[XMLParser alloc]
    stripUnwantedStringChars:string]];

这分配了一个新的XMLParser并且永远不会摆脱它。

于 2010-01-31T00:10:05.237 回答
1

我试图弄清楚你在分配给 tempString 时最终做了什么。如果你这样做:

self.tempString = [NSMutableString string];

那么你必须在 dealloc 中释放 tempString。即使它是自动发布的,setter 也会保留它。

于 2010-02-01T02:34:56.953 回答
0

首先,我想这实际上应该崩溃,因为自动释放的可变字符串应该在您从 parserDidStartDocument 返回后不久释放。这并不令人担忧,而且您还声称该财产在没有保留时被保留,从而在您的财产定义中撒谎。

但是,Leaks 告诉您的是字符串的副本已泄漏 - Leaks 向您显示了泄漏对象的分配位置,但这不是泄漏的原因。泄漏的原因是您没有应该稍后正确释放该字符串的代码行。由于 Leaks 无法指向不存在的代码,因此它只能向您显示导致对象未正确释放的原因。

在这种情况下,我认为您缺少的是数组应该包含自动释放的对象 - 所以您想说:

[entryDict setObject:[[tempString copy] autorelease] forKey:kXMLDictDateKey];

因为 Copy 还保留了副本(就像 alloc/init 一样)。

于 2010-01-30T23:01:40.073 回答