6

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

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

在这个论坛上提到了双下划线的使用,因为它与 C 相关——它是为了“编译器的内部使用”。我想我不明白这在这种情况下如何适用。

我的应用程序中需要一个 ViewController,其行为与 SQLiteBooks 示例项目中的 ViewController 非常相似,但这个双下划线让我感到困惑。

4

4 回答 4

20

C 编译器和 Objective-C 编译器对带有前导下划线的变量名的处理与任何其他变量名都没有任何不同。单下划线或双前导下划线只是一种约定,有效地形成了一个命名空间,很像NSCocoa 类中使用的前缀,如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 有一个非常好的重命名重构,它会自动为您完成)。

于 2009-02-19T19:07:11.720 回答
6

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

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

Apple 传统上使用单个下划线前缀来表示私有实例变量(面向对象语言中的常见样式)。这被认为是暗示每个人都应该在他们的 ivars 前加上下划线,直到 Apple 指出如果 Apple 决定更改其标头而在您的代码中使用下划线可能会与 Cocoa 发生冲突,也许您不应该这样做。所以下划线前缀已经成为一种“不建议”的编码习惯。

在 C 和 C 派生语言中,任何前后带有双下划线的单词都是非标准语言扩展。查看 Apple 的扩展,例如 __attribute__

尾随下划线通常作为原始名称的编译器或调试器名称错位版本添加(尤其是当编译器是多通道时),并且通常避免使用,以便这些名称与原始名称保持明显不同。谷歌在他们的 Objective-C 本地实例变量后面加上下划线以避免与 Apple 的下划线冲突。

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

于 2009-02-19T23:42:47.600 回答
2

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

于 2009-02-19T18:43:07.577 回答
0

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

您所指的帖子是关于定义的,而不是变量。许多编译器对其提供和依赖的定义使用双下划线。

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

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

于 2009-02-19T18:46:10.070 回答