XML 解析器中 NSMutableString 的内存泄漏
我在我的应用程序中使用 XMLparser。它运行良好,但是当我在仪器中运行我的应用程序时,我不断在处理来自 XML 的字符串的 NSMutableString 处遇到内存泄漏。
令人讨厌的是,这种内存泄漏仅在我第二次执行特定调用(登录)时才会发生。当我进行其他调用时,我不会出现内存泄漏。
造成泄漏的 NSMutableString 是“textInProgress”。
- (NSDictionary *)objectWithData:(NSData *)data
{
[dictionaryStack release];
[textInProgress release];
dictionaryStack = [[NSMutableArray alloc] init];
textInProgress = [[NSMutableString alloc] init];
[dictionaryStack addObject:[NSMutableDictionary dictionary]];
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
parser.delegate = self;
BOOL success = [parser parse];
[parser release];
if (success)
{
NSDictionary *resultDict = [dictionaryStack objectAtIndex:0];
return resultDict;
}
return nil;
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
NSMutableDictionary *parentDict = [dictionaryStack lastObject];
NSMutableDictionary *childDict = [NSMutableDictionary dictionary];
[childDict setObject:attributeDict forKey: NODE_ATTR_KEY];
id existingValue = [parentDict objectForKey:elementName];
if (existingValue)
{
NSMutableArray *array = nil;
if ([existingValue isKindOfClass:[NSMutableArray class]])
{
array = (NSMutableArray *) existingValue;
}
else
{
array = [NSMutableArray array];
[array addObject:existingValue];
[parentDict setObject:array forKey:elementName];
}
[array addObject:childDict];
}
else
{
[parentDict setObject:childDict forKey:elementName];
}
[dictionaryStack addObject:childDict];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
NSMutableDictionary *dictInProgress = [dictionaryStack lastObject];
if ([textInProgress length] > 0)
{
[dictInProgress setObject:textInProgress forKey:NODE_VALUE_KEY];
[textInProgress release];
textInProgress = [[NSMutableString alloc] init]; <--- Object leaks here
}
[dictionaryStack removeLastObject];
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
[textInProgress appendString:string]; <--- Object leaks here
}
我调试了一整天,仍然找不到解决这个问题的方法。泄漏仅包含 64 字节数据。
这里还有两张仪器内泄漏的屏幕截图 ->泄漏->调用树
希望有人能帮助我!
编辑:
这些泄漏的解决方案是将 NSMutableString 和 NSMutableDictionary 声明为属性。 (参考Neal他的评论)
I'm using an XMLparser within my App. It's running fine however when I run my App in instruments I keep getting memory leaks at a NSMutableString which handles the strings which came out of the XML.
Weard thing is that this memory leak only occurs when I do a specific call (login) for the second time. When I do other calls I don't get a memory leak.
The NSMutableString which gives the leaks is 'textInProgress'.
- (NSDictionary *)objectWithData:(NSData *)data
{
[dictionaryStack release];
[textInProgress release];
dictionaryStack = [[NSMutableArray alloc] init];
textInProgress = [[NSMutableString alloc] init];
[dictionaryStack addObject:[NSMutableDictionary dictionary]];
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
parser.delegate = self;
BOOL success = [parser parse];
[parser release];
if (success)
{
NSDictionary *resultDict = [dictionaryStack objectAtIndex:0];
return resultDict;
}
return nil;
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
NSMutableDictionary *parentDict = [dictionaryStack lastObject];
NSMutableDictionary *childDict = [NSMutableDictionary dictionary];
[childDict setObject:attributeDict forKey: NODE_ATTR_KEY];
id existingValue = [parentDict objectForKey:elementName];
if (existingValue)
{
NSMutableArray *array = nil;
if ([existingValue isKindOfClass:[NSMutableArray class]])
{
array = (NSMutableArray *) existingValue;
}
else
{
array = [NSMutableArray array];
[array addObject:existingValue];
[parentDict setObject:array forKey:elementName];
}
[array addObject:childDict];
}
else
{
[parentDict setObject:childDict forKey:elementName];
}
[dictionaryStack addObject:childDict];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
NSMutableDictionary *dictInProgress = [dictionaryStack lastObject];
if ([textInProgress length] > 0)
{
[dictInProgress setObject:textInProgress forKey:NODE_VALUE_KEY];
[textInProgress release];
textInProgress = [[NSMutableString alloc] init]; <--- Object leaks here
}
[dictionaryStack removeLastObject];
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
[textInProgress appendString:string]; <--- Object leaks here
}
I've been debuggin all day and still can't find a solution for this problem. The leak only contains 64 bytes of data.
Here are also two screenshots of the leak within instruments -> Leaks -> Call tree
Hope someone can help me out!
EDIT:
The solution for these leaks was to declare the NSMutableString and NSMutableDictionary as a property. (Refer to Neal his comment)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我建议您将
textInProgress
转换为属性而不是 ivar。像这样:并且只需确保在
dealloc
中释放它即可。Protip:如果您也更改了属性相应 ivar 的名称(例如
_textInProgress
),您将得到一个在您之前使用 ivar 的每个点上都会出现构建错误,因此您不会错过从textInProgress
到self.textInProgress
的任何更改I would advise that you convert
textInProgress
to a property rather than an ivar. Like this:And just make sure that you release it in
dealloc
Protip: If you change the name of the property's corresponding ivar as well (e.g.
_textInProgress
), you will get a build error at each point where you used the ivar before, so you won't miss any changes fromtextInProgress
toself.textInProgress