Objective-C:在命名变量中使用_(下划线)

Objective-C: using _ (underscores) in naming variables

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

Possible Duplicate:
Prefixing property names with an underscore in Objective C

在我正在读的Objective-C书中,在我看到的一些代码中,有时人们会在变量名中添加下划线。

当我意识到这是由于一个既定的惯例,我想:

下划线是在变量名前面还是在变量名后面?例如,以_name, name and name_为目标C程序员,如果有的话,下划线对您意味着什么呢?


这在很大程度上取决于个人风格和防御性编程。但这就是我个人使用并看到人们使用前缀的主要原因。

这是为了让你的意图更清楚地知道你是直接访问IVAR还是使用getter/setter。

如果我有:

1
@property (nonatomic, retain) NSArray *people;

还有:

1
@synthesize people = _people;

这将编译并生成getter/setter声明,如下所示:

1
2
- (void)setPeople:(NSArray *)people;
- (NSArray *)people;

现在要直接访问IVAR,我需要使用:

1
_people

要使用getter/setter,我可以使用点表示法或getter/setter,如:

1
2
3
4
5
6
7
8
[self people];
// or
self.people; // which compiles to [self people];

// and
[self setPeople:newPeople];
// or
self.people = newPeople; // which compiles to [self setPeople:newPeople];

现在在我的代码中,如果我不小心只键入:

1
people = newPeople; // will not compile

它不会编译,因为我没有使用getter/setter,也没有名为people的ivar,它应该是_people


一个前导下划线是一个苹果内部编码约定,他们这样做是为了让他们的符号不会与你的符号冲突。不幸的是,苹果在发布遵循这个习惯的代码示例方面一直很马虎,所以很多苹果以外的人都认为这是一件好事。

如果要在ivar和方法名上使用前缀,请使用除单个前导下划线之外的任何内容。


如果您确实使用了这样的变量名,那么您绝对不应该使用以下划线开头,后跟大写字母的任何变量名。C标准保留所有此类标识符,以供任何使用(§7.1.3):

All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.

也就是说,未来的C语言版本(或给定的编译器)可能会使用任何这样的标识符作为关键字或库函数名,这可能会破坏程序。有鉴于此,我更喜欢简单地不使用带下划线前缀的名称;您可能知道在下划线后不使用大写字母,但这并不能阻止新来的人来做这件事。

此外,所有以下划线开头的标识符都保留在文件范围内;另一个需要注意的问题是。


下划线表示private,i人员不使用它我的self-ivars,因为您可以始终使用@private,并且可以将ivar添加到.m文件中的接口扩展或甚至代码的@implementaion部分,它最近随着属性的出现而变得常见,因此您可以使用它来保护自己,以防意外访问ivar i。N代码,而不是属性,因为编译器可以告诉你的错误,在C编程中,我经常使用领先的分数来显示一个函数不是自包含的,它将被另一个函数使用,也会在IVAR中使用C++,因为C++不喜欢成员函数和IVAR具有相同的名称。


下划线实际上并不意味着什么,但是当你使用它的时候,很难犯这样的错误,但是我从未见过有人在末尾使用下划线,只是在开头,并且会建议你不要在结尾添加下划线,因为这可能不清楚它们的含义。

我并没有在目标C代码中添加下划线,但这主要是一个品味问题,而不是意义问题。请确保不要在名称的中间或结尾添加下划线:)