【问题标题】:Objective-C properties - is using [self myProperty] or self.myProperty slower than myProperty?Objective-C 属性 - 使用 [self myProperty] 或 self.myProperty 是否比 myProperty 慢?
【发布时间】:2011-10-05 19:02:49
【问题描述】:

我正在使用 Objective-C 属性为我处理保留/释放实例变量。在我的课堂上,我正在做这样的事情:

self.myProperty = somethingIWantToRetain
[self.myProperty doSomeAction]
[self.myProperty doSomethingElse]

使用 [self myProperty] / self.myProperty 是否比在我不更改 myProperty 值的行中简单地使用 myProperty 慢?例如,以下会更快吗?

self.myProperty = somethingIWantToRetain
[myProperty doSomeAction]
[myProperty doSomethingElse]

谢谢

【问题讨论】:

    标签: iphone objective-c properties


    【解决方案1】:

    准确地说,当你写[myProperty doSomeAction]时,你实际上并不是在访问属性,而是直接访问实例变量(用作属性的后备变量)。

    您只能使用点符号[self.myProperty doSomeAction] 访问属性(通过它的setter 和getter)(或者通过像[[self myProperty] doSomeAction] 一样显式调用setter/getter,这是完全等价的,因为这是编译器翻译成的编译代码时)

    所以当你写[myProperty doSomeAction]时,因为它直接访问变量——与[self.myProperty doSomeAction]相反,它调用myProperty的getter从而进行额外的方法调用/消息发送——那么理论上它会更快您将获得一条消息发送。

    但实际上您不会看到任何改进,因此无需考虑直接访问该变量(如果您以后想以其他方式实现它,它会使您失去灵活性)


    此外,如果您使用 Modern Runtime(如果您为任何版本的 iOS 编写代码,Legacy Runtime 仅用于 32 位 Mac OSX),则不需要显式定义属性的支持变量了。因此,您可以在 .h 中声明 @property 并在 .m 中声明 @synthesize 而不使用任何实例变量(编译器将在编译时为您生成它),在这种情况下您将无法调用(不存在的)实例变量! (至少不在@synthesize 指令之前)

    【讨论】:

    • 您答案的最后一部分不正确。曾经有一个编译器错误阻止了它,但可以使用合成的 ivar。请参阅 my answer 到“什么是现代运行时?”。
    • 是的,你说得对,我同意,我只是为了简单起见才写的;请注意,您只能在代码中的 @synthesize 指令之后使用 ivar 。 (其实我觉得没有自己创建的ivar最好不要依赖,只有在这种情况下直接使用属性)。但是感谢您指出这一点,很高兴知道这仍然是一种可能性;)
    【解决方案2】:

    在操作中多一步变慢?是的。 明显或实际更慢?绝对不是。

    您必须记住,现代 CPU 每秒运行数百万次操作的程序。在几乎所有语言中,调用 getter 方法与访问 ivar 本身的速度基本相同(尤其是当 getter 方法中没有其他代码时)。

    使用 getter 而不是直接访问 ivars 是个好习惯,所以我不会试图通过忽略它们来“加快速度”。

    【讨论】:

      【解决方案3】:

      使用 Objective-C 2.0 点语法相当于调用 getter,所以第一个 sn-p 会慢一些,因为你会产生两个额外的动态调度。

      话虽如此,损失将是轻微的,显然您将获得能够在以后更改 setter 和 getter 的灵活性(例如,如果您最终将该值隐含以使其在技术上不被存储在内存中,或者将其传递给第三个对象,或者执行一些异步存储,这可能需要您在某些情况下阻塞 getter)。

      【讨论】:

        【解决方案4】:

        是的,它会稍微快一些,但通过进行这种微优化不太可能显着提高性能。如果您使用self.myProperty,您可以稍后决定实现不同的访问器方法,而无需在任何地方更改您的代码。

        【讨论】:

          【解决方案5】:

          几乎可以肯定它会慢一点,但不太重要。

          直接引用您的 ivar(使用裸 myProperty)直接访问变量。引用您的属性 getter(具有等效的 self.myProperty[self myProperty])必须调用一个方法,该方法通常会在您的 ivar 上执行 retainautorelease

          然而,Objective-C 中的方法调度非常非常快,并且保留/自动释放调用也非常便宜,特别是对于在自动释放池被清除时可能不会被销毁的对象。我会专注于可读性和一致的风格,只有当你很明显有性能瓶颈要追逐时才担心这里的性能。

          【讨论】:

            猜你喜欢
            • 2018-08-29
            • 1970-01-01
            • 2021-08-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-06-02
            • 1970-01-01
            • 2021-04-05
            相关资源
            最近更新 更多