在目标 C 中设置保留声明属性的设置方法有何区别?



根据苹果开发者网站:实用内存管理,在实现自定义设置方法的保留属性如下:

@interface Counter : NSObject
@property (nonatomic, retain) NSNumber *count;
@end;
- (void)setCount:(NSNumber *)newCount {
[newCount retain];
[_count release];
// Make the new assignment.
_count = newCount;
}

但许多网站建议第一步应该是发布。例如,在这个问题:目标 c - @properties (MRC( 的显式 getter/setters - 堆栈溢出中,答案给出了另一种实现。

- (void)setCount:(NSNumber *)count {
if (count != _count) {
NSNumber *oldCount = _count;
// retain before releasing the old one, in order to avoid other threads to
// ever accessing a released object through the `_count` pointer.
_count = [count retain];
// safely release the old one.
[oldCount release];
}
}

所以我怀疑这两种实现之间的区别哪一个是首选,为什么?

感谢您的关注和回答。

区别是微妙的,但是如果您为其赋值,则可以释放该对象:

id x = self.thing;
self.thing = x;

因此,我们的精神始终是先保留新的,然后再释放旧的

打开 ARC,这些废话都消失了。

我真的没有看到任何关于为什么在发布后会调用保留的论据。但是,我可以找到为什么不先发布它的论据。

如果先释放旧对象,则可能会释放新对象并随之解除分配。这将是一个非常具体的情况,但它可能会发生。显然不是NSNumber,而是例如认为这是一个UIView,新值是旧值的子视图。现在,旧值具有对新值的引用,并保留它。通过释放旧值,您肯定会减少新值的保留计数。对于保留计数降至零并释放对象也必须有点特殊,但同样,这可能是有意义的。

所以一般来说,当你得到一个对象时,你必须首先保留它。之后,您可以开始修改任何其他数据。

最新更新