iPhone Obj C代码中的内存泄漏

时间:2009-08-11 23:30:55

标签: iphone memory-management

我正在解析XML字符串并且有内存泄漏。我知道这段代码正在泄漏,但不确定修复是什么:

http://pastie.org/580694

这样的代码似乎存在根本缺陷:

- (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];

但不确定我应该如何处理抓住找到的角色并保留/释放它们。

感谢

2 个答案:

答案 0 :(得分:1)

Problem类的定义中,让编译器为您处理属性内存管理:

  • 使用@property (retain) NSString *desc;定义字符串属性。这将确保您的类增加它存储的字符串值的引用计数(如果稍后存储另一个值,则减少它)。
  • 使用@property (assign) int problemId定义int属性。 Int不需要复制重新计数。

dealloc:方法中,请务必释放所有保留的属性,例如[desc release]

最后,在分配到value的属性之前,您无需复制currentProblemcurrentProblem.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];

-copythree magic words之一,这意味着保留了返回的值,然后在setter中再次保留它。所以你是双重保留;记忆泄漏。

value是NSString,因此是不可变的。没有理由复制它。许多指针可以安全地共享不可变对象。此代码应为:

currentProblem.desc = value;

这一行有点不同:

currentProblem.problemId = [[value copy] intValue];

在这种情况下,problemId显然是一个赋值属性(或者你很快会崩溃),但是你仍然在-copy上调用value,导致其保留计数增加一个,因此泄漏它。此代码应为:

currentProblem.problemId = [value intValue];

简而言之,请停止在此处复制对象,并且您的内存泄漏将会消失。在ObjC中复制有点罕见。