我创建了一个小测试项目来尝试解决我在主项目中遇到的问题。我注意到,当从容器中检索对象时,引用计数不会增加。
我很困惑,为什么不是这样?
例如,此代码不会增加hereDoggy对象的引用计数:
//Retrieve the dog, why does this not increment the reference count?
Dog* hereDoggy = [cont1 objectAtIndex:0];
以下是完整示例:
-(void)doZombieProblem
{
NSMutableArray* cont1 = [NSMutableArray array];
NSMutableArray* cont2 = [NSMutableArray array];
NSMutableArray* cont3 = nil;
//Create the dog pointer
Dog* doggy = [[Dog alloc] initWithName:@"Bernard"];
//Add to container1
[cont1 addObject:doggy];
//Release the dog pointer
[doggy release];
while ([cont1 count] > 0)
{
//Retrieve the dog, why does this not increment the reference count?
Dog* hereDoggy = [cont1 objectAtIndex:0];
//Add it to cont2
[cont2 addObject:hereDoggy];
//Remove it from cont1.
[cont1 removeObjectAtIndex:0];
//No need to release as we haven't increased the reference count.
//[hereDoggy release];
}
//I should be able to retrieve the dog here from cont2.
Dog* bernard = [cont2 objectAtIndex:0];
//No need to release as we haven't increased the reference count.
//[bernard release];
}
答案 0 :(得分:4)
在这种情况下,如果您想增加对象的保留计数,则需要发送retain
(或copy
)消息。
您需要始终将retain
(或copy
)与release
进行平衡。如果你不这样做,你可能会有内存泄漏。否则切换到ARC功能,以避免编写代码量并缩短您的生活。
这是了解内存管理如何工作的有用链接。
我评论了你的代码以了解发生了什么:
// the object referenced by doggy has a retain count of 1
Dog* doggy = [[Dog alloc] initWithName:@"Bernard"];
// now the retain count is 2 since you added to a container class like NSArray
[cont1 addObject:doggy];
// now the retain count is 1
[doggy release];
然后,在while
声明中:
// the retain count still remains 1
Dog* hereDoggy = [cont1 objectAtIndex:0];
// the retain count increases to 2
[cont2 addObject:hereDoggy];
// the retain count goes to 1
[cont1 removeObjectAtIndex:0];
因为,cont2
您可以访问该对象,所以可以访问该对象。
如果你[cont2 removeObjectAtIndex:0];
保留计数达到0并且对象被自动释放。
答案 1 :(得分:2)
作为对象的用户,您有责任管理它的保留计数。这是因为只有您(消费者)知道您何时完成它。这就是为什么只是调用[cont1 objectAtIndex:0]
不会增加它。 NSArray不知道你对它返回的对象有什么计划。
考虑保留计数以指示拥有某物的事物的数量。当它为0时,没有人拥有它,所以让它被垃圾收集。如果它是1,那么只有一件事需要它/拥有它(并且在上面)。
当你调用[cont1 addObject:doggy]
时,NSMutableArray绝对会增加它的保留计数(在幕后),就像你调用[cont1 removeObjectAtIndex:0]
时一样,NSMutableArray会减少它的保留计数。
现在,如果您在任何时间段内需要hereDoggy
,请自行致电retain
,然后在适当的时候release
。