我来自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
有人能发现我在这里做错了吗?
答案 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.
部分,因为它保留了对象(或者您必须稍后手动释放它。保留对象的@property
是copy
和retain
答案 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)
检查属性cardCellArray
是retain
还是copy
。如果是这样,当您致电self.cardCellArray
时,您设置为属性cardCellArray
的对象会将保留计数增加 1。
使用alloc
创建对象& init
(例如initWithCapacity:
)会返回一个保留计数为1的对象,因为您在此处调用了alloc
方法。
虽然创建没有调用alloc
的对象(例如[NSMutableArray arrayWithCapacity:]
)将返回autorelease
对象(它会在需要时自动将其保留计数减1),但您可以认为它保留了计数0。 / p>
dealloc
中的,您应该调用[self.cardCellArray release]
,这将自动删除数组保留的所有对象。
此处的代码在
之后生成一个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