iPhone应用程序内存泄漏

时间:2012-05-07 00:47:44

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

我来自C背景,并且你们很多人都知道Objective-C是从C派生的。我假设内存管理概念是相似的。我收到关于潜在内存泄漏的警告但是奇怪的是我在alloc之后释放了对象。看一下这个例子:

self.cardCellArray = [[NSMutableArray alloc] initWithCapacity:kTotalNumberOfCards];

并在dealloc中:

- (void) dealloc
{
[super dealloc];
[self.cardCellArray removeAllObjects];
}

我得到的内存泄漏消息是:

Method returns an Objective-C object with a +1 retain count

Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1

有人能发现我在这里做错了吗?

4 个答案:

答案 0 :(得分:4)

我假设cardCellArray属性是拥有引用(即保留或复制)。

self.cardCellArray = [[NSMutableArray alloc] initWithCapacity:kTotalNumberOfCards];

这应该是:

self.cardCellArray = [[[NSMutableArray alloc] initWithCapacity:kTotalNumberOfCards] autorelease];

甚至:

cardCellArray = [[NSMutableArray alloc] initWithCapacity:kTotalNumberOfCards];

确保内存管理正确。

此外,dealloc方法应该是:

- (void)dealloc
{
   [cardCellArray release];
   [super dealloc];
}

这假设cardCellArray属性的实例变量名为cardCellArray。

答案 1 :(得分:3)

您没有释放数组,而只是清空它。 另请注意,我将[super dealloc]调用移到了最后一行,这是因为带有实例变量的对象后来在dealloc链中被完全释放,因此您将尝试访问释放的内存。

- (void) dealloc
{
   [cardCellArray release];
   [super dealloc];
}

另一件事:您使用self.cardCellArray =,取决于您的@property对于ivar的样子,您可能必须删除self.部分,因为它保留了对象(或者您必须稍后手动释放它。保留对象的@propertycopyretain

答案 2 :(得分:1)

是的,正如JustSid建议您双重保留阵列并且永远不会释放它。

虽然Objective-C堆管理的根源在于C,但管理各个对象的方式完全不同。

您没有说明属性cardCellArray是如何定义的,但可能是定义为retained,这样,当您分配给self.cardCellArray时,您实际上是在执行该方法setCardCellArray,该方法“保留”该对象。但是由于你的alloc电话已经保留了它,所以现在它被保留了两次。

然后,在dealloc方法中,您根本不会release。您可以通过执行[cardCellArray release];或执行self.cardCellArray = nil;来释放对象。要么释放它(但只有一次 - 你需要用双重保留来解决你的问题)。

需要进行removeAllObjects调用。当您release一个对象(并且保留计数变为零)时,将调用该对象的dealloc方法,并执行适合其引用的对象的发布。

(正如Sid建议的那样,最后拨打[super dealloc]。)

(但是,当然,上面的所有内容都在ARC的窗口外面,你可以担心一些全新的,不同的东西,你可以搞砸了。)

答案 3 :(得分:1)

  1. 检查属性cardCellArrayretain还是copy。如果是这样,当您致电self.cardCellArray时,您设置为属性cardCellArray的对象会将保留计数增加 1。

  2. 使用alloc创建对象& init(例如initWithCapacity:)会返回一个保留计数为1的对象,因为您在此处调用了alloc方法。

    虽然创建没有调用alloc的对象(例如[NSMutableArray arrayWithCapacity:])将返回autorelease对象(它会在需要时自动将其保留计数减1),但您可以认为它保留了计数0。 / p>

  3. 方法dealloc中的
  4. ,您应该调用[self.cardCellArray release],这将自动删除数组保留的所有对象。

  5. 此处的代码在

    之后生成一个retain-count-1对象

    [[NSMutableArray alloc] initWithCapacity:kTotalNumberOfCards]

    当你打电话给

    时,这个对象的保留计数变为2

    self.cardCellArray = xxx

    但是在dealloc中你没有减少cardCellArray的保留计数,然后发生泄漏。

    所以将代码更改为

    self.cardCellArray = [[[NSMutableArray alloc] initWithCapacity:kTotalNumberOfCards] autorelease];

    autorelease会在需要时自动减少保留计数。

    self.cardCellArray = [NSMutableArray arrayWithCapacity:kTotalNumberOfCards];

    NSMutableArray *_array = [[NSMutableArray alloc] initWithCapacity:kTotalNumberOfCards];
    self.cardCellArray = _array;
    [_array release];
    

    cardCellArray = [[NSMutableArray alloc] initWithCapacity:kTotalNumberOfCards];
    //this helps because it doesn't call `[self setCardCellArray]` which generate +1 retain count.
    

    最后,记得在dealloc方法中发布cardCellArray