0

这是一个setter方法的实现:

- (void)setCount:(NSNumber *)newCount {
    [newCount retain];
    [_count release];
    // Make the new assignment.
    _count = newCount;
}

如果retainCountof _countis <=0,它如何释放?

4

2 回答 2

4

唯一可以保留计数为 0 的有效对象是nil. 并且发送任何消息nil只返回 0 而不做任何其他事情,因此这种情况已涵盖。

如果你的意思是“这怎么能与一个释放的对象一起工作”——好吧,它不能。一个被释放的对象的保留计数并不是真正的 0,因为该对象不再存在——它已经被销毁,现在只是一块内存——所以它没有任何属性。对释放的对象做任何事情都是无效的,并且会发生什么是未定义的。

于 2013-04-09T17:18:49.490 回答
3

想象一个带有retainCount实例变量的类。

@implementation MyClass
{
   NSUInteger retainCount;
}

- (id) retain {
    retainCount++;
    return self;
}

- (void) release {
    if (retainCount > 1)
        retainCount--;
    else
        [self dealloc];
}
...
@end

一旦一个对象被释放,它就死了,消失了,完成了,等等......因此,将retainCount减为0是没有意义的,因为根据定义,对象将被释放并与一个释放的对象一起工作是未定义的行为。

上面是 NSObject 的确切逻辑,但是完全不同的实现(你真的不想看到 NSObject 的实际实现——这很痛苦)。


混淆的另一个来源似乎是引用的含义。

 NSObject *foo;
 char *bar;
 NSUInteger baz;

出于所有意图和目的,上述三个变量声明的行为相同[在手动保留/释放中]。

当你说 时bar = "Hello, World!";,你是在告诉编译器'复制包含字符串“Hello, World!”的内存地址。到名为bar“”的内存中。同样foo,只有您要复制包含该类实例的内存地址NSObject

现在,baz可能看起来不一样了。但它确实不是,只是它包含数字,而不是地址。但是,真的,地址就是一个数字!

所以,在一个二传手::

- (void)setCount:(NSNumber *)newCount {
    // increment newCount's retain count
    [newCount retain];
    // decrement the _count's retain count (which may cause it to be deallocated or not)
    [_count release];
    // copy the address of the memory that holds the NSNumber instance referenced
    // by `newCount` into the instance variable `_count`.
    _count = newCount;
}

该分配没有什么神奇的[在手动保留释放下]。它只是将一个数字从一个变量复制到另一个变量。对象完全不受此影响。

于 2013-04-10T15:24:59.510 回答