Setter方法真的在Obj-C中做吗?

时间:2013-04-09 17:16:12

标签: objective-c release

这是setter方法的实现:

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

retainCount的{​​{1}}是< = 0,它是如何释放的?

2 个答案:

答案 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;
}

在[手动保留释放]下,没有任何关于该任务的神奇之处。它只是将一个数字从一个变量复制到另一个变量。这个对象完全没有受到影响。