【问题标题】:@synthesize ivarName = _ivarName convention, preference or performance? [duplicate]@synthesize ivarName = _ivarName 约定、偏好或性能? [复制]
【发布时间】:2011-11-30 22:32:41
【问题描述】:

可能重复:
Synthesized property and variable with underscore prefix: what does this mean?

我一直觉得 Objective-C 属性的使用很尴尬。这是“我知道如何使用它们,但我并不总是确定为什么要使用它们”之一。类似的事情,最近我看到了很多这样的事情:

// in .h file
@interface MyObject : NSObject
{
     id _coolIvar;
}
@property (assign) id coolIvar;
@end

// in .m file
@implementation
@synthesize coolIvar = _coolIvar;// <- whats the point of that.
@end

那么使用下划线声明 ivar 然后使用 @synthesize 访问它有什么意义,而不是仅声明与 ivar 同名的 @property?

附带问题: 我注意到这种约定变得越来越流行,因为块开始成为异步回调的首选方法,而不是目标/选择器方法。这是巧合还是上面的@property 声明约定更适合块作用域?

【问题讨论】:

    标签: objective-c coding-style properties naming-conventions


    【解决方案1】:

    这是偏好。

    我也不喜欢两次声明变量,而是让它们像这样合成:

    // in .h file
    @interface MyObject : NSObject
    @property (assign) id coolIvar;
    @end
    
    // in .m file
    @implementation
    @synthesize coolIvar = _coolIvar;
    @end
    

    我喜欢使用_前缀的两个原因是

    1. 我知道什么时候通过访问器,什么时候直接访问变量。
    2. 如果调用 ivar address 对我来说是有意义的,那么在方法内部很可能在逻辑上也将类似的变量称为 address。如果我的 ivar 没有 _ 前缀,那么我的本地 address 将屏蔽 ivar address

    我也喜欢 xcode 如何在您开始输入 @synthesize myVar = _... 时自动完成以 _ 开头的变量

    注意
    您可能会遇到奇怪的名称冲突(我只有一次),但编译器给您的警告使它成为一个非常容易的地方,只需更改名称即可快速获胜。

    @isaac 谈到了不声明 ivars,以便它们不会被公开宣传,但没有解释如何/为什么。基本上,您可以在类扩展中声明 @property,以仍然为您提供 @synthesized getter/setter 的好处,但不会让您的公共 API 看起来很丑。

    您之前的示例如下所示(如果您希望 coolIvar 不被公开宣传):

    // in .h file
    @interface MyObject : NSObject
    @end
    
    // in .m file
    @interface MyObject () <-- Like a category but with no name
    @property (assign) id coolIvar;
    @end
    
    @implementation
    @synthesize coolIvar = _coolIvar;
    @end
    

    【讨论】:

    • 哦,哇,太酷了。我不知道您可以像这样隐式声明 ivars。是时候去冗长一些代码了哈哈。谢谢。
    【解决方案2】:

    当我真正打算通过访问器时,我使用 _ivar 构造来确保不会直接(错误地)访问 ivar。

    【讨论】:

      【解决方案3】:

      使用现代运行时(iPhone 应用程序和 Mac OS X v10.5 及更高版本上的 64 位程序)不再需要 ivar 声明。所以你的代码被简化为:

      // in .h file
      @interface MyObject : NSObject
      
      @property (assign) id coolIvar;
      
      @end
      
      // in .m file
      @implementation
      
      @synthesize coolIvar = _coolIvar;
      
      @end
      

      根据@Monolo 的回答,_ivar 是一个很好的故障保护措施,可确保您不会无意中直接访问 ivar。请记住,@property@synthesize 可以替换样板代码 - 没有它,您将不得不编写 getter 和 setter 访问器。

      【讨论】:

        【解决方案4】:

        将 ivars 与属性访问器区分开来有几个好处。

        Monolo 描述了一个 - 当您打算访问的是属性时,它可以防止错误地访问 ivar。

        另一个是理论上它可以防止冲突 - 在这种情况下,您可能将 ivar 命名为与您的实现之外的另一个 ivar 相同的名称(即超类 ivar 名称)。

        关于最佳实践有不同的想法,但最近我在几个我认为可靠的地方读到,最佳实践实际上是不再在您的接口中声明 ivars(通过属性声明隐式创建 ivars) .

        有些人不喜欢“隐含” - 但有物质利益:不声明它们可以避免广告不公开的 ivars。它在避免冲突方面也走得更远——因为理论上,当一个属性被合成并生成 ivar 时,它不会引入一个本身可能与私有 ivar 命名约定冲突的约定(可能是前面或尾随的情况)下划线)。

        【讨论】:

          【解决方案5】:

          偏好。有些人喜欢在实例变量前加上下划线(这样可以很容易地判断一个人是在引用 ivar,还是在更本地范围内的变量),而有些人则不喜欢。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-12-30
            • 2013-12-29
            • 2017-06-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多