2009-02-19 36 views
6

Objective-C中的单个下划线显然是为Apple的“内部”使用保留的(并且可以在Apple声明之前与私有实例变量一起使用)。但为什么他们会在iPhone的SQLiteBooks示例中使用double -underscore?看到这个片段来自MasterViewController.m采取:Cocoa中的这种双下划线是什么

+ (EditingViewController *)editingViewController { 
    // Instantiate the editing view controller if necessary. 
    if (__editingViewController == nil) { 
     __editingViewController = [[EditingViewController alloc] initWithNibName:@"EditingView" bundle:nil]; 
    } 
    return __editingViewController; 
} 

有这个forum的双下划线使用提,因为它涉及到C - 这是对“compier内部使用。”我想我没有看到在这种情况下如何适用。

我需要一个ViewController在我的应用程序中表现得非常像SQLiteBooks示例项目中的一个,但是这种双下划线让我感到困惑。

回答

20

C编译器和Objective-C编译器都不用任何其他变量名称来区别带有前导下划线的变量名。单引号或双引号下划线只是一个约定并且有效地形成一个命名空间,非常类似NSString等Cocoa类中使用的NS前缀。

望着SQLiteBooks代码,MasterViewController.m这个定义静态全局变量:

// Manage the editing view controller from this class so it can be easily accessed from both the detail and add controllers. 
static EditingViewController *__editingViewController = nil; 

所以我的猜测是,SQLiteBooks的作者采用了双领先下划线来表示全局变量。

C编译器(以及扩展Objective-C)保留名称,以两个下划线和一个大写字母开头供编译器供应商使用,给它们一个保留的名称空间以用于全局变量和用于实现标准库的函数,或引入新的非标准关键字__block

尽管SQLiteBooks代码在技术上是有效的,但在我看来,它很容易与保留的名称空间混淆。如果你确实重用了这段代码,我建议重命名该变量(Xcode有一个很好的重命名重构,它会自动为你做)。

2

这只是一个变量命名约定。它没有什么。这是程序编写者提醒自己的一种方式,“这是一个私有变量”。

+0

那么你是说现在Apple已经声称它已经被内部使用,现在它已经被替换掉了一个下划线? – Meltemi 2009-02-19 18:46:02

+0

这忽略了问题的实际问题。 – 2009-02-19 18:46:33

+1

是的,它和Apple的单下划线一样。 (不,安德鲁,我不相信自己错过了这一点,他问他们为什么使用双下划线,我解释过。) – Chuck 2009-02-19 18:52:53

0

编译器/库供应商将某些前/后缀表示为“保留”的情况并不少见。这主要是为了避免类型/定义/继承变量之间的无意的冲突。

你引用的帖子是关于定义,而不是变量。许多编译器对它们提供和依赖的定义使用双下划线。

至于为什么它的示例代码使用这种风格 - 原作者使用相同的编码风格,他可能在日常工作中使用,潜在的冲突从未突出。

你应该很好地保留代码示例,但如果它让你感到不舒服,那么你可以重命名该变量。

6

对于编译器,下划线被视为任何字母字符。更一般地说,下划线通常由语言扩展或大型库使用,以避免与用户代码冲突。

使用下划线是有问题的,因为很多组尝试使用特定的下划线组合来保留每个名称。

Apple传统上使用一个下划线前缀来表示一个私有实例变量(面向对象语言中的一种常见样式)。这意味着每个人都应该给他们的ivars加下划线,直到Apple指出在Apple代码中使用下划线可能会与Cocoa产生冲突,如果Apple决定改变他们的头文件,也许你不应该这样做。因此,下划线前缀已经成为“不建议”的编码实践。

在C和C衍生语言中,任何带有双下划线前后两个字的词都是非标准语言扩展。请参阅Apple的扩展,如__attribute__

尾随下划线通常作为编译器或调试器名称的原始名称的损坏版本(特别是在编译器为多路传输时)添加并且通常被避免,以便这些名称与原始文件明显不同。谷歌将它们的Objective-C本地实例变量后缀加下划线,以避免与Apple的下划线发生冲突。

我的建议:不要使用下划线。你不应该使用与实例变量同名的局部变量(这只是令人困惑)。唯一的潜在冲突是setter方法中的参数与相应的实例变量之间的冲突 - 您应该在参数前面加上小写的“a”,“new”(或类似的),因为这明确指出参数是传入值但还不是“价值”。

相关问题