2012-05-07 27 views
0

我来自C背景,很多人都知道Objective-C是从C派生的。我认为内存管理概念是相似的。我收到了关于潜在内存泄漏的警告,但奇怪的是,我在alloc之后释放该对象。在这个例子看看:iPhone应用程序中的内存泄漏

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

任何人都可以发现我在这里做错了吗?

回答

1
  1. 检查。如果是这样,当你调用self.cardCellArray,对象设置财产cardCellArray得到保留计数由1

  2. 创建使用alloc & init(如initWithCapacity:)返回与保留计数1对象对象增加,因为你在这里调用了一个alloc方法。

    尽管没有调用创建对象alloc[NSMutableArray arrayWithCapacity:]将返回autorelease对象(它会自动降低它在需要的时候通过1保留计数),你可以考虑它在方法dealloc保持数0

  3. ,你应该调用[self.cardCellArray release],这会自动删除数组保留的所有对象。

你的代码在这里产生一个保留-数-1对象后

[[NSMutableArray alloc] initWithCapacity:kTotalNumberOfCards]

这个对象的保留计数成为2,当你调用

self.cardCellArray = xxx

但是在dealloc中,你并没有减少cardCellArray的保留计数t母鸡泄漏发生。

所以你的代码更改为

self.cardCellArray = [[[NSMutableArray alloc] initWithCapacity:kTotalNumberOfCards] 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

3

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

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

另一件事:您正在使用self.cardCellArray =,这取决于伊娃您@property的样子,你可能有,因为它保留了对象去除self.部分(或者你有以后手动释放)。 @property的保留对象是copyretain

+0

removeallobjects吧?我只是用这个作为例子,我有很多其他人有点莫名其妙地让我发布其中一个 – godzilla

+0

@godzilla更新我的回答 – JustSid

+0

啊所以如果我有@property(nonatomic,retain)NSMutableArray * uncontrolledCards;并做一self.cardCellArray =我实际上复制不传递参考? – godzilla

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

是的,正如JustSid建议您双重保留数组并永不释放它。

虽然Objective-C堆管理在C中有根,但是管理单个对象的方式完全不同。

你不说怎么财产cardCellArray定义,但据推测它定义为retained,使得当分配给self.cardCellArray,你真的执行方法setCardCellArray,并且该方法“保留”的对象。但由于您的电话号码已被保留,所以现在它保留两次。

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

你做需要做​​电话。当release对象(并且保留计数为零)时,会调用该对象的dealloc方法,并执行适用于其引用对象的版本。

(正如希德建议,做[super dealloc]最后调用。)

(当然,以上的一切都是出于与ARC,在这里你不用担心一个完全新的和不同的一套东西的窗口中如果属性是cardCellArrayretain可以copy搞砸。)

+0

感谢您的回应,你可以请告知以下内容:如果我有一个NSString与保留属性,我做了一个[self setFileName:[[NSString alloc] initWithFormat:@“Pentagon.png”]];我是否分配了两次? – godzilla

+0

@godzilla - 你会保留两次。 'alloc'基本上就像C中的malloc一样,只是它对原始对象头进行了一些额外的设置,其中一部分是对保留计数进行增量。 (你真的需要在Objective-C上找到一本好书(或者至少是一本书),并研究堆管理的东西 - 这不是你可以在街上轻松拾取的东西。) –