3

XCodeテンプレート(少なくともXCode 4.3.2)に、いくつかのivarの前に2つのアンダースコアが付いているものと、1つしかないものがある理由を知っている人はいますか?

たとえば、Master-DetailアプリケーションテンプレートにはファイルMasterViewController.mが含まれており、次の場所にあります。

@synthesize detailViewController = _detailViewController;
@synthesize fetchedResultsController = __fetchedResultsController;
@synthesize managedObjectContext = __managedObjectContext;

ありがとう。

4

1 に答える 1

5

それはワームの小さな缶です。

アンダースコアは、主にインスタンス変数をアクセサー名と区別するために@synthesizeで使用されます。これは、特にアクセサ内の変数にアクセスするだけではない場合(たとえば、遅延初期化)に重要です。それらが同じ名前である場合、アクセサメソッドを呼び出す「self.foo」を意味するときに、簡単に「foo」と入力してインスタンス変数を取得できます。したがって、そのコンテキストでアンダースコアが使用されるのはそのためです。

さて、Appleは、プライベートメソッド名に先頭の下線を使用すべきではないと言っています。彼らはプライベートメソッド名にその規則を使用しており、基本クラスのメソッドの1つを意図せずにオーバーライドする可能性があります。特にコンパイル時にこれをキャッチできないため、これは悪いことです。

ただし、プライベートインスタンス変数にアンダースコアを使用しても問題ないとのことです。実際、例として、プロパティの合成でivarに先頭のアンダースコアを使用することは完全にOK(および提案)であると彼らは言います。

さて、これがキャッチです。また、プライベートインスタンス変数に単一の先頭の下線を使用します。したがって、同じ名前の場合、競合が発生する可能性があります。これを確認するために、View Controllerメソッドの実装では、「_」を使用して、どのコード補完があなたの道を投げるかを確認します。

では、なぜ彼らはこの命名慣行を思いとどまらせないのでしょうか?コンパイル時に競合が発生するためです。同じ名前の2つのインスタンス変数を持つことはできません。これを行おうとすると、エラーが発生します。

では、なぜ彼らのコードテンプレートは二重アンダースコアで名前を生成するのですか?知らない。「実装」は実際には先頭の二重アンダースコア(大文字が続く)を予約しますが、__blockのようなObjCの追加が見られます。

私のお金のために、私は先頭に二重下線が付いているものは何も避けます。Appleは、生成されたコードでやりたいことを何でもできます。FWIW、ARC用に生成されたコードの一部はまだ古い非ARCキーワードを参照しているため、生成されたコードを福音とは見なしません。FWIW、私は間違いなく、CoreData用に生成されたコードを保持しません。最低限、(managedObjectContextアクセサメソッドで)変更する必要があります。

__managedObjectContext = [[NSManagedObjectContext alloc] init];

__managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];

余談ですが、私は人々が個人的な合成名として先頭または末尾の文字としてドル記号を使用しているのを見てきました。

@synthesize foo = $foo;
@synthesize bar = bar$;

私は25年以上C/C ++を書いていますが、ObjCはかなり新しいので、独自の複雑さがあります。ですから、私は言語弁護士ではありません。私はパラリーガルでもありません。私が知っているのは、それが合法であるように見えることだけです。ドル記号が他の目的に使用されることを想定していないことは確かではありませんが、私が試したすべてのことで機能します。Xcode構文ハイライトはそれを好みません(変数名の残りの部分で色付けしません)。

それがあなたの質問に答えるのに十分なものになったと思いますが、それはおそらくあなたをより多くの質問に駆り立てました...

于 2012-04-21T13:08:29.483 に答える