这是setter方法的实现:
- (void)setCount:(NSNumber *)newCount {
[newCount retain];
[_count release];
// Make the new assignment.
_count = newCount;
}
retainCount
的{{1}}是< = 0,它是如何释放的?
答案 0 :(得分:4)
唯一可以保留计数为0的有效对象是nil
。 <_ 1}}发送任何消息只返回0而不做任何其他事情,因此该案例已被涵盖。
如果你的意思是“如何使用解除分配的对象” - 嗯,它不能。并且释放对象的保留计数实际上不是0,因为该对象不再存在 - 它已被破坏,现在只是一块内存 - 所以它没有任何属性。对解除分配的对象执行任何操作都是无效的,将会发生什么是未定义的。
答案 1 :(得分: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
似乎有所不同。但它确实不是,它包含数字,而不是地址。但是,实际上,地址是一个数字!
所以,在setter ::
中- (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;
}
在[手动保留释放]下,没有任何关于该任务的神奇之处。它只是将一个数字从一个变量复制到另一个变量。这个对象完全没有受到影响。