从容器中检索对象时,为什么引用计数不增加?

时间:2012-06-24 16:26:02

标签: objective-c ios reference

我创建了一个小测试项目来尝试解决我在主项目中遇到的问题。我注意到,当从容器中检索对象时,引用计数不会增加。

我很困惑,为什么不是这样?

例如,此代码不会增加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];
}

2 个答案:

答案 0 :(得分:4)

在这种情况下,如果您想增加对象的保留计数,则需要发送retain(或copy)消息。

根据经验

您需要始终将retain(或copy)与release进行平衡。如果你不这样做,你可能会有内存泄漏。否则切换到ARC功能,以避免编写代码量并缩短您的生活。

这是了解内存管理如何工作的有用链接。

MemoryMgmt

我评论了你的代码以了解发生了什么:

// 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