私よりずっと賢いマーク・ダーリンプルは、このテーマについてビッグ・ナード・ランチにブログ投稿を書きました。結論:アンダースコアは良い考えです。リンクが将来機能しなくなった場合に備えて、ここで彼の投稿を要約しますが、可能であれば、私の要約の代わりに彼の投稿を読む必要があります。
明示的に呼び出すこと@synthesize
が必須だったときに、彼はこの投稿を書き戻しました。彼は次のようなコードを提唱しました。
// soapbubble.m
@synthesize viscosity = _viscosity;
@synthesize detergentBrand = _detergentBrand;
最近のXcodeには、自動的かつ暗黙的にが含まれています@synthesize
。そして、それは前に付けられたアンダースコアを使ってそうするので、どうやらAppleのエンジニアはMarkに同意しているようだ。
彼の最初の理由は文体です。これにより、どの変数がローカルで、どの変数がセッターの引数であるかを簡単に確認できます。
- (void) setPonyName: (NSString *) ponyName {
[_ponyName autorelease];
_ponyName = [ponyName copy];
}
(これはARC以前のセッターであるため、この方法は完全に不要になりますが、セッターが単に値を解放して割り当てる以外の複雑な処理を行った場合でも、適用されます。)
彼の2番目の理由(そして私がより重要だと思う理由)は、追跡が非常に難しい特定のクラスのバグを排除することです。
このコード:
self.ponyName = @"Mikey";
と同じです:
[self setPonyName: @"Mikey"];
アンダースコアが付加されていない場合、このコードも有効です。
ponyName = @"Mikey";
ただし、セッターは呼び出されないため、セッターに副作用は発生しません。繰り返しますが、ローカル変数の値を変更する以外にセッターが余分な作業を行う状況では、これは大きな頭痛の種になる可能性があります。アンダースコアを前に付けると、その行でコンパイルエラーが発生します。ローカル変数を設定することについては、非常に明確にする必要があります。
_ponyName = @"Mikey";
そして、あなたが良心的なプログラマーであるため、この不規則な操作を実行している理由を正確に説明するコメントを含めることになります。