【问题标题】:What's the difference of the set method that set a retain declared property in Objective C?在Objective C中设置保留声明属性的set方法有什么区别?
【发布时间】:2020-01-21 09:59:16
【问题描述】:

根据苹果开发者网站:Practical Memory Management,在retain属性的自定义set方法的实现如下:

@interface Counter : NSObject
@property (nonatomic, retain) NSNumber *count;
@end;

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

但许多网站建议第一步应该是发布。比如这个问题:objective c - Explicit getters/setters for @properties (MRC) - Stack Overflow,答案给出了另一种实现。

 - (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];
    }
}

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

感谢您的关注和回答。

【问题讨论】:

  • 可能只是开启了ARC?
  • 您对为什么有些网站建议先发布有意见吗?在你的第二个 sn-p release 之后也调用 retain
  • ARC 遵循第二个 sn-p (包括另一个答案中提到的测试)。自己决定这是否使它成为“首选”。
  • @Cy-4AH 这是一个建议先发布的网站。 stackoverflow.com/questions/5040702/…

标签: objective-c memory-management


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    区别是微妙的,但是如果你给自己赋值,那么你可以释放对象:

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

    所以精神总是先保留新的,然后释放旧的

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

    【讨论】:

    • 所以我们需要先检查 count != _count 吗?
    • @doit 这可能行得通,但通常只使用问题中的第一个实现更简单。
    • @doit – 这正是第二个 sn-p(和 ARC)所做的。
    猜你喜欢
    • 1970-01-01
    • 2011-11-09
    • 2013-09-11
    • 1970-01-01
    • 1970-01-01
    • 2011-01-16
    • 2011-11-03
    • 2013-04-12
    • 2015-08-19
    相关资源
    最近更新 更多