0

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

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

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

2 回答 2

4

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

根据经验

您需要始终平衡您retain的 s(或copyies)与您release的 s。如果你不这样做,你可能会出现内存泄漏。否则切换到 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 并且对象将自动释放。

于 2012-06-24T16:44:00.317 回答
2

作为对象的用户,您有责任管理它的保留计数。这是因为只有你,消费者,知道你什么时候完成。这就是为什么只是调用[cont1 objectAtIndex:0]不会增加它。NSArray 不知道你对它返回的对象有什么计划。

考虑保留计数来表示拥有某物的事物的数量。当它为 0 时,没有人拥有它,所以让它被垃圾收集。如果它是 1,那么只有 1 个东西需要它/拥有它(并且一直如此)。

当你调用[cont1 addObject:doggy]NSMutableArray 将绝对增加它的保留计数(在幕后),就像你调用[cont1 removeObjectAtIndex:0]NSMutableArray 时会减少它的保留计数一样。

现在,如果您需要hereDoggy任何时间,只需retain自己调用它,然后release在适当的时候调用。

于 2012-06-24T16:29:29.683 回答