【问题标题】:Compiler says there is a memory leak, but I don't see one编译器说有内存泄漏,但我没有看到
【发布时间】:2011-09-21 02:24:41
【问题描述】:

所以我用 Xcode 做了那个你说分析的事情,它发现了泄漏和东西,在这里,它说我正在泄漏(在下面的代码中标记)。

// Copy dictionary to memory
NSString *filepath = [[NSBundle mainBundle] pathForResource:@"DataCategoriesDictionary" ofType:@"plist"];
NSDictionary *dataCategoriesDictionary = [[NSDictionary alloc] initWithContentsOfFile:filepath];
self.choices = [[NSMutableDictionary alloc] initWithDictionary:[dataCategoriesDictionary objectForKey:self.chosenCategory]]; // LINE 55
[dataCategoriesDictionary release]; // HERE, the compiler says "Potential leak of an object allocated on line 55"

尽管泄漏实例变量没有任何意义,但我还是尝试为其添加发布语句,但 Xcode 仍然给了我同样的错误。我还能泄露什么?

【问题讨论】:

  • 你双击那一行(分析问题行),它会告诉你为什么这样说。

标签: iphone objective-c xcode memory-management memory-leaks


【解决方案1】:

如果choices 是一个带有retain 的属性,你就是在泄露NSMutableDictionary。

[[NSMutableDictionary alloc] initWithDictionary

要么自动释放,要么使用临时的。

self.choices = [[[NSMutableDictionary alloc] initWithDictionary:[dataCategoriesDictionary objectForKey:self.chosenCategory]] autorelease];

或(我最喜欢的)

self.choices = [NSMutableDictionary dictionaryWithDictionary:[dataCategoriesDictionary objectForKey:self.chosenCategory];

NSMutableDictionary *tempDict = [[NSMutableDictionary alloc] initWithDictionary:[dataCategoriesDictionary objectForKey:self.chosenCategory]];
self.choices = tempDict;
[tempDict release];

【讨论】:

  • 为了最简单,请使用便捷构造函数+dictionaryWithDictionary:!
  • 代码越少越好,我将其添加为一个选项。谢谢提醒!
  • [choices release];,后跟choices = [[NS.. alloc] init...];(用实际的实例变量名称替换语句中的“选择”。)
  • 如果choices是一个属性,看起来真的是,最好使用setter/getter,不要破坏属性ivar管理。例外是 init 和 dealloc。
【解决方案2】:

choices 看起来像 Declared Property。您似乎已像下面这样声明它:

在 .h 文件中:
@property (nonatomic, retain) NSMutableDictionary *choices;

在 .m 文件中:
@synthesize choices

这种情况下,编译器会自动提供setter方法:

-(void) setChoices:(NSMutableDictionary*)newValue
{
    if (choices != newValue) {
        [choices release];
        choices = [newValue retain];
    }
}

从您的代码中,self.choices 隐式调用 setChoices 方法。所以新分配的NSMutableDictionary的retain count变成2而不是1,导致对象泄漏。

【讨论】:

    【解决方案3】:

    您应该释放属性choice 引用的成员变量(ivar)。所以假设有一个成员变量_choice 然后像这样释放它:

    [_choice release]
    

    应该可以。

    或者,如果你像这样重写它,可能会更清楚为什么会有泄漏:

    NSMutableDictionary * temp = [[NSMutableDictionary alloc] initWithDictionary:[dataCategoriesDictionary 
    self.choices = temp
    [temp release]
    

    【讨论】:

    • 如果选择是一个不释放的属性,分配给该属性会释放当前值并保留新值。稍后当分配完成并且释放当前值时,将会有过度释放。
    • @CocoaFu:我不关注。我没有看到额外的释放会发生在哪里?
    • @CocoaFu:释放成员变量是正确的,因为这将正确更新释放计数。请参阅此处:stackoverflow.com/questions/7577453/…
    猜你喜欢
    • 2011-03-13
    • 1970-01-01
    • 2012-01-11
    • 2013-04-30
    • 1970-01-01
    • 1970-01-01
    • 2016-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多