在setter中不必要的释放

时间:2012-02-20 19:21:06

标签: objective-c memory-management accessor

有许多setter的例子我们应该怎么做,例如:

- (void)setFoo:(NSString *)newFoo
{
    if (foo != newFoo)
    {
        [foo release];//??
        foo = [newFoo retain];
    }
}

我理解我们需要释放prev值,然后分配一个带保留的新值,这就是文档说我们要做的事情,但如果指定foo = [newFoo retain]我无法理解我们应该发布什么;将使用newFoo的当前保留计数器使foo成为一个新值,如果foo的保留计数器之前是5,它将成为newFoo的+ 1,或者我错过了一些并且理解不正确。为什么我们不能这样做:

- (void)setFoo:(NSString *)newFoo
{
     if (foo != newFoo)
     {
         foo = [newFoo retain];
     }
}

2 个答案:

答案 0 :(得分:1)

Objective-C适用于指针(一切都是指针)。

执行retainrelease时,您没有在引用/指针(您的变量名称)上执行此操作,而是在实际对象本身上执行此操作。

这就是为什么我们需要释放旧对象(因为我们已经完成它),并将我们的变量指向新的,然后增加其retain计数,因此它不会被删除别的东西)。

希望有意义

答案 1 :(得分:0)

foo是指向存储在内存中的NSString对象的指针(内存地址)。当这个setter函数启动时,内存中有两个NSString对象:一个被foo指向并保留,另一个作为参数传入。每个对象都有自己的保留计数。

foo == newFoo告诉指针停止指向旧的NSString,然后开始指向新的NSString。

如果在更改指针之前没有释放第一个对象,则会导致内存泄漏。旧对象没有任何指向它的东西(因此它不存在,只要你的程序知道),但是它的保留计数永远不会达到0并且因为它仍然被保留而被取消分配。