6

Objective-C の単一のアンダースコアは、Apple の「内部」使用のために予約されているようです (Apple が主張する前は、プライベート インスタンス変数で使用できました)。しかし、なぜ彼らは、iPhone の SQLiteBooks の例で2つのアンダースコアを使用するのでしょうか? MasterViewController.m から取得したこのスニペットを参照してください。

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

このフォーラムでは、C に関連する二重アンダースコアの使用について言及されています。これは、「コンパイラの内部使用」のためのものです。この状況でそれがどのように適用されるかはわかりません。

SQLiteBooks サンプル プロジェクトと同じように動作する ViewController がアプリに必要ですが、この 2 つのアンダースコアには困惑しています。

4

4 に答える 4

20

C コンパイラも Objective-C コンパイラも、アンダースコアが先頭にある変数名を他の変数名とはまったく異なる方法で処理しません。先頭の 1 つまたは 2 つのアンダースコアは単なる規則であり、効果的に名前空間を形成します。NSNSString

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 の作成者は、グローバル変数を示すために先頭に 2 つのアンダースコアを使用しています。

C コンパイラ (および拡張 Objective-C) は、コンパイラ ベンダーが使用するために 2 つのアンダースコアと大文字で始まる名前を予約し、標準ライブラリを実装するために使用されるグローバル変数と関数に使用する予約済みの名前空間を提供します。 - のような標準的なキーワード__block

SQLiteBooks のコードは技術的には有効ですが、予約済みの名前空間と混同しやすいと思います。そのコードを再利用する場合は、その変数の名前を変更することをお勧めします (Xcode には、自動的にそれを行う非常に優れた名前変更リファクタリングがあります)。

于 2009-02-19T19:07:11.720 に答える
6

コンパイラにとって、アンダースコアはアルファベット文字のように扱われます。より一般的には、アンダースコアは通常、ユーザー コードとの競合を避けるために、言語拡張機能や大規模なライブラリで使用されます。

多くのグループがすべての名前を特定のアンダースコアの組み合わせで予約しようとするため、アンダースコアの使用には問題があります。

Apple は伝統的に、単一のアンダースコア プレフィックスを使用してプライベート インスタンス変数を示してきました (オブジェクト指向言語で一般的なスタイル)。これは、Apple がヘッダーを変更することを決定した場合、コードでアンダースコアを使用すると Cocoa との競合が発生する可能性があることを Apple が指摘するまで、誰もが ivar の前にアンダースコアを付ける必要があることを意味するものでした。そのため、アンダースコア プレフィックスは「推奨されない」コーディング プラクティスになりました。

C および C 派生言語では、前後にアンダースコアが 2 つ付いている単語は、非標準の言語拡張です。__attribute__ などの Apple の拡張機能を参照してください

末尾のアンダースコアは、多くの場合、元の名前のコンパイラまたはデバッガ名のマングル バージョン (特にコンパイラがマルチパスの場合) として追加され、これらの名前が元の名前と明確に区​​別されるように通常は回避されます。Google は、Apple のアンダースコアとの競合を避けるために、Objective-C のローカル インスタンス変数にアンダースコアを付けています。

私のアドバイス: アンダースコアを使用しないでください。インスタンス変数と同じ名前のローカル変数を使用するべきではありません (混乱するだけです)。唯一の潜在的な競合は、setter メソッドのパラメーターと対応するインスタンス変数の間です。おそらく、パラメーターの前に小文字の "a"、"new" (または同様のもの) を付ける必要があります。これは、パラメーターが入力値であることを明確に示しているためです。しかし、まだ「その」値ではありません。

于 2009-02-19T23:42:47.600 に答える
2

これは単なる変数の命名規則です。何もしませ。これは、プログラム作成者が「これはプライベート変数です」と思い出させる方法です。

于 2009-02-19T18:43:07.577 に答える
0

コンパイラ/ライブラリベンダーが特定のプリ/ポストフィクスを「予約済み」と指定することは珍しくありません。これは主に、型/定義/継承された変数間の不注意による競合を回避するためです。

あなたが参照している投稿は、変数ではなく、定義に関するものです。多くのコンパイラは、提供および依存する定義に二重アンダースコアを使用します。

サンプルコードがこのスタイルを使用している理由については、元の作成者が日常業務で使用している可能性が高いのと同じコーディングスタイルを使用しており、潜在的な競合が強調されることはありませんでした。

コードサンプルをそのまま保持しても問題ないはずですが、不快な場合は変数の名前を変更できます。

于 2009-02-19T18:46:10.070 に答える