iPhone ivar命名约定

时间:2010-01-22 02:33:25

标签: iphone objective-c

  

可能重复:
  How does an underscore in front of a variable in a cocoa objective-c class work?

我注意到在很多参考资料中,我发现很多时候,变量在.h文件中被命名为_variable,然后在.m文件中被@ synthesize为< / p>

@synthesize variable = _variable;

为什么这样做?我错过了什么?

谢谢!

7 个答案:

答案 0 :(得分:21)

对此没有达成共识。有些人喜欢使用它来清楚地分离出类变量,而另一个响应者注意到避免与传入的参数名冲突。即使在Apple示例代码中,使用情况也是喜忧参半。

但是,我更倾向于不使用_前缀,并且有两个强有力的理由:

1)有些人认为_是“私人”的良好指标。我的看法是,应该在没有setter / getter(属性)的情况下访问NO类局部变量,因此它们都是私有的 - 假设为什么不以更容易阅读和使用自动完成的方式命名它们?编译器可以快速显示参数名称的任何重叠,并通过更周密的参数命名(或内部变量)来避免。

2)(更好的理由) - 如果在XCode中使用“refactor”,内部类var的名称与用于访问它的属性相同,则属性和synthesize语句也将被重命名。如果对前缀为_的类变量使用重构,则不会更改属性名称 - 只需将合成映射到内部名称。我几乎从不希望名称从属性变化到它公开访问的实际变量。仅此一点就让我永远不想使用_作为变量前缀,因为能够移动名称只是提高代码清晰度所能做的最有用的事情。

答案 1 :(得分:15)

使用该语法可以更清楚地表明ivar和属性是不同的东西。

要对类外部进行编码,因为它使用了属性,所以没有区别。

对于类本身实现中的代码,它可以使ivar在使用时更清晰。

例如,假设我们有一个NSNumber对象的ivar / property:

@interface MyClass : NSObject {
    NSNumber *num;
}
@property (nonatomic, retain) NSNumber *num;
- (void)doSomething;
@end

@implementation MyClass
@synthesize num;

- (void)doSomething {
    // set the property, num is properly retained
    self.num = [NSNumber numberWithInteger:1];

    // accidentally set the ivar, num is NOT retained
    num = [NSNumber numberWithInteger:2];
}
@end

现在为ivar和属性使用不同的名称:

@interface MyClass : NSObject {
    NSNumber *i_num;
}
@property (nonatomic, retain) NSNumber *num;
- (void)doSomething;
@end

@implementation MyClass
@synthesize num = i_num;

- (void)doSomething {
    // set the property, num is properly retained
    self.num = [NSNumber numberWithInteger:1];

    // compiler error, there is no ivar named "num"
    num = [NSNumber numberWithInteger:2];

    // set the ivar, so it needs to be a retained object
    i_num = [[NSNumber alloc] initWithInteger:3];
}
@end

答案 2 :(得分:9)

以前的答案缺少这背后的历史。在Objective-C 2.0之前,没有属性。所以你有一个像这样的实例变量的对象:

@interface MyObject: NSObject {
    NSArray *myArray;
}

@end

但是你如何从其他对象访问它们?解决方案是制造孵化器和吸气剂。但为了避免混淆,他们会这样做:

@interface MyObject: NSObject {
    NSArray *_myArray;
}

- (NSArray *)myArray;
- (void)setMyArray:(NSArray *)myArray;

@end

_用于清除实例变量_myArray和方法-myArray之间的混淆。

答案 3 :(得分:4)

有时人们使用mVarName(C ++),而在Obj-c中,样式似乎是_varName。 你可以遇到的一个问题是,假设你对一个函数的参数是... set:(int)x - 但是 - 你有一个名为x的iVar ......你会让编译器为这样的东西哭泣 - 不是提到它令人困惑。

m,_,有助于显示该类的成员属性。

 -(void) set:(int)x
{
 x = x; // x is an ivar! heh
}

VS

 -(void) set:(int)x
{
 _x = x; // ahh I see!
}

答案 4 :(得分:1)

这纯粹是惯例。我认为它很常见,因为当你做一个方法getter调用时这样:

[myObject variable]

您实际上正在调用方法,而不是直接访问变量。前面的_表明你在谈论一个变量。就个人而言,我发现这种语法令人烦恼并且分散注意力。我认为这是不必要的,但你是对的,它确实出现在这里和那里。

答案 5 :(得分:1)

我不想使用'_'前缀,因为Apple确实一直使用它。通过避免使用前缀,我更有信心,当我扩展可可触摸类时,我的ivars不会与Apple碰撞。由于我们无法访问基类的源代码,因此这是我所知道的唯一避免意外重用现有私有ivars的方法。

很像

  

以“_”开头的方法名称(单个下划线字符)保留供Apple使用。

答案 6 :(得分:0)

我的偏好,在Google之后,只是附加一个下划线并明确合成(即使我重新实现):

@synthesize varName=varName_;

如果我在init...dealloc或访问者之外看到尾随下划线,我知道有些东西可疑。