Cocoa的这个双下划线是什么?

时间:2009-02-19 18:39:33

标签: objective-c cocoa double-underscore

Objective-C中的单个下划线显然是为Apple的“内部”使用保留的(并且在Apple声明之前可用于私有实例变量)。但是为什么他们会在他们的SQLiteBooks示例中为iPhone使用 double -underscore?请参阅从MasterViewController.m获取的此片段:

+ (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示例项目中的一样,但是这个双下划线让我感到困惑。

4 个答案:

答案 0 :(得分:20)

C编译器和Objective-C编译器都不会将带有前导下划线的变量名称与任何其他变量名称区别对待。单个或双重前导下划线只是一个约定并且有效地形成了一个名称空间,就像NS等Cocoa类中使用的NSString前缀一样。

查看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有一个非常好的重命名重构,可以自动为您完成)。

答案 1 :(得分:6)

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

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

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

在C和C衍生语言中,任何前后都有双下划线的单词都是非标准语言扩展。请参阅Apple的扩展名,例如__attribute __

尾随下划线通常作为原始名称的编译器或调试器名称损坏版本添加(特别是当编译器是多遍时)并且通常被避免,以使这些名称与原件明显不同。 Google使用下划线为其Objective-C本地实例变量添加后缀,以避免与Apple的下划线冲突。

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

答案 2 :(得分:2)

这只是一个变量命名约定。它不会任何事情。这是程序编写者提醒自己的一种方式,“这是一个私有变量。”

答案 3 :(得分:0)

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

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

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

您应该保持原样保留代码示例,但如果它让您感到不舒服,那么您可以重命名该变量。