关于iphone:什么时候在实例变量前面加下划线?

When do you make an underscore in front of an instance variable?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
How does an underscore in front of a variable in a cocoa objective-c class work?

我在苹果的uipikerview.h中看到过这个:

1
id<UIPickerViewDataSource> _dataSource;

为什么要强调这一点?它有特殊的意义吗?我必须知道的惯例?


很多人将它用于私有变量,以区分对象中的私有变量和公共变量。

这是一种完全可选的工作方式。


您看到的是使用下划线区分实例变量和属性。所以类声明可以是:

1
2
3
4
5
6
@interface Foo {
  NSString* _label;
  ....
}

@property (nonatomic, retain) NSString* label; // notice: no underline

然后在实现文件中,您将拥有:

1
@synthesize label=_label; // the property is matched with the ivar

现在,在实现内部,如果您想要直接访问实例变量,您可以使用_label,但是要通过属性访问器方法(它负责保留/发布和其他一些簿记任务),您可以使用self.label。从外面看,你总是想通过{object}.label的财产。

另一种方法是不使用下划线,只使用:

1
2
3
4
NSString* label;
@property (nonatomic, retain) NSString* label;
...
@synthesize label;

它的工作原理是一样的,但随后它可能会混淆某些人读取代码并试图跟踪labelself.label。我个人认为苹果大会(带下划线)更容易阅读,但这是一个偏好问题。


正如人们所说,已经有人用somevar来表示变量是私有的。这只是一个简单的惯例问题,并不真正重要。

另一种用法是,在返回机器中使用c a_函数()表示一个不可平台移植的函数,而_u函数()表示一个不可编译器移植的函数。所以,在标准的C库中,有时会看到一个变量的名称前面有一个或一个,这就是这些函数所代表的。


我用下划线来表示变量是一个成员,类似于匈牙利符号中的"m"前缀(我彻底鄙视这个符号,但这是另一回事)。当然,这些天你会得到颜色编码编辑器,但我的观点是,前缀让你在输入变量之前考虑变量是一个成员/实例,而不仅仅是在你的编辑器得到颜色编码之后。


是不是…(点动记忆)

我隐约记得我读过一篇ADC文档,解释说苹果保留使用带下划线前缀的成员变量?第三方开发人员不鼓励使用此约定以避免冲突?

K <


它有时用来表示私有变量。更一般地说,它只是意味着"这个变量在某种程度上是不同的"。


我选择对ivar使用下划线,因为我经常遇到以下情况:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@interface MyClass:NSObject
{
    NSUInteger count;
}

@property(nonatomic) NSUInteger count;  

-(id) initWithCount(NSUInteger) count;


@end

(...)

@implementation MyClass
@synthesize count;

-(id) initWithCount(NSUInteger) count
{
    if((self = [super init])){
        self.count = count; // Parameter name collides with ivar name!
    }
    return self;
}

@end

所以我这样做:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@interface MyClass:NSObject
{
    NSUInteger _count;
}

@property(nonatomic) NSUInteger count;  

-(id) initWithCount(NSUInteger) count;

@end

(...)

@implementation MyClass
@synthesize count = _count;

-(id) initWithCount(NSUInteger) count
{
    if((self = [super init])){
        _count = count; // No name collision
    }
    return self;
}

@end

当然,我也可以将参数名改为"NewCount"或"AcCount"(我讨厌这个)。我认为这是一个品味问题。


一般来说,它表示一个变量不应该被开发人员直接接触。这不是真正的需求,但是如果你不能避免在一个你不想被弄乱的类中有一个公共变量,这是一个很好的实践。