【问题标题】:How is an assign @property's setter implemented?分配@property 的setter 是如何实现的?
【发布时间】:2011-11-03 17:45:44
【问题描述】:

setter 的实现是否在将 ivar 分配给新值之前首先检查新值是否与旧值不同?

是否有说明如何合成属性的所有不同排列(取决于属性、assignretain 等)的文档(或源代码)参考?

【问题讨论】:

    标签: objective-c properties getter-setter assign


    【解决方案1】:

    我无法想象分配设置器首先检查以前的值。这将完全浪费 CPU 周期,因为无论哪种方式结果都是一样的。文档明确说明了各种属性的语义,但并未准确显示合成了哪些代码。

    【讨论】:

    • 在新值等于旧值的情况下会不会节省 CPU 周期,因为这样 CPU 就不必浪费周期将实例变量重置为新值了?跨度>
    • @MattDiPasquale,如果它们相同,是的,您可以节省分配给变量的操作,但您需要预先支付条件检查费用。在值不同的(最常见的)情况下,您现在要为条件和赋值付出代价,弊大于利。
    • @Matt 最好简单地设置它(load>mov),而不是load>load>compare>(branch ? mov : nop)。使用原子,它甚至更加复杂。当操作更重要时(例如保留或复制的属性),比较是值得的。伪汇编。
    【解决方案2】:

    Objective-C 文档对此进行了解释。实际发生的细节是特定于实现的。

    复制
    指定对象的副本应该用于 任务。先前的值被发送一个释放消息。副本是 通过调用复制方法制作。该属性仅对 对象类型,必须实现 NSCopying 协议。

    分配
    指定 setter 使用简单赋值。这个属性是 默认值。您将此属性用于标量类型,例如 NSInteger 和 CGRect。

    保留
    指定应在 分配对象。之前的值被发送释放消息。

    ...

    非原子
    指定访问器是非原子的。默认情况下,访问器是原子的。

    ...

    [_internal lock]; // lock using an object-level lock
    id result = [[value retain] autorelease];
    [_internal unlock];
    return result;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-09
      • 1970-01-01
      • 2020-07-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多