我正在解析XML字符串并且有内存泄漏。我知道这段代码正在泄漏,但不确定修复是什么:
这样的代码似乎存在根本缺陷:
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)value{
if ([currentElement isEqualToString:@"problem_id"]){
currentProblem.problemId = [[value copy] intValue];
} else if ([currentElement isEqualToString:@"rule_instance_id"]){
currentProblem.ruleInstanceId = [value copy];
} else if ([currentElement isEqualToString:@"description"]){
currentProblem.desc = [value copy];
} else if ([currentElement isEqualToString:@"name"]){
currentProblem.name = [value copy];
但不确定我应该如何处理抓住找到的角色并保留/释放它们。
感谢
答案 0 :(得分:1)
在Problem
类的定义中,让编译器为您处理属性内存管理:
@property (retain) NSString *desc;
定义字符串属性。这将确保您的类增加它存储的字符串值的引用计数(如果稍后存储另一个值,则减少它)。@property (assign) int problemId
定义int属性。 Int不需要复制重新计数。在dealloc:
方法中,请务必释放所有保留的属性,例如[desc release]
。
最后,在分配到value
的属性之前,您无需复制currentProblem
。 currentProblem.desc = value
会做正确的事。如果你留下[value copy]
,那就会继续泄漏。
至于问题中的代码,它在几个地方泄漏:
[[value copy] intValue]
时,parser:foundCharacters:
都会泄漏,因为副本永远不会被释放。currentProblem
时,currentProblem
的字符串成员会泄漏,因为dealloc:
的当前实现不会释放它们。答案 1 :(得分:1)
currentProblem.problemId = ...
相当于[currentProblem setProblemId:...]
。您几乎肯定已声明problemId具有保留或复制setter,因此setProblemId:
保留传递的对象。这很正常。
currentProblem.desc = [value copy];
-copy
是three magic words之一,这意味着保留了返回的值,然后在setter中再次保留它。所以你是双重保留;记忆泄漏。
value
是NSString,因此是不可变的。没有理由复制它。许多指针可以安全地共享不可变对象。此代码应为:
currentProblem.desc = value;
这一行有点不同:
currentProblem.problemId = [[value copy] intValue];
在这种情况下,problemId显然是一个赋值属性(或者你很快会崩溃),但是你仍然在-copy
上调用value
,导致其保留计数增加一个,因此泄漏它。此代码应为:
currentProblem.problemId = [value intValue];
简而言之,请停止在此处复制对象,并且您的内存泄漏将会消失。在ObjC中复制有点罕见。