2011-11-16 6 views
8

可能性の重複:
How does an underscore in front of a variable in a cocoa objective-c class work?(目的C)@synthesize myvar = _myvar(もしあれば)の利点は何ですか?

あなたはときに、アンダースコアの接頭辞で内部変数を作成したい理由は、(コードの可読性以外の)私には完全には明らかではありませんプロパティを作成します。

ゲッターとセッターにコードを追加しないので、すべてが内部的に処理されるため、なぜそうしないのですか?

ゲッターやセッターにいくつかのコードを追加する必要がある場合でも、なぜ私は_myvarをチェックしてからmyvarに割り当てる必要があるのではなく、なぜmyvarでチェックするだけでいいのか分かりません。

誰も私に何か説明をしてもらえますか?「それは誰もがやっているのですから」私はこの習慣の背後にあるすべての理由を理解したいと思います(getterとsetterのカスタムコードがなくてもかなり一般的です)。

ありがとうございます!

+1

多く、多くのがあります。この質問の重複:[1](http://stackoverflow.com/questions/3521254/)[2](http://stackoverflow.com/questions/822487/)[3](http://stackoverflow.com/questions/2371489)[4](http://stackoverflow.com/questions/5582448/)[5](http://stackoverflow.com/questions/837559/)[6](http://stackoverflow.com/questions/6064283 /)[and more ...](http://stackoverflow.com/search?q=objc+property+underscore) –

答えて

8

Objective-Cプロパティには、通常、バッキングインスタンス変数があります(プロパティとインスタンス変数の違いを知っていると思います)。

プロパティの名前がインスタンス変数と異なる場合があります。

たとえば、という名前のインスタンス変数があり、プロパティがyとなっている可能性があります。

あなたは使用してx変数にyプロパティを合成することができます

@synthesize y = x; 

を今すぐアンダースコアについて。

インスタンス変数と同じ名前のメソッド引数を持つ場合、命名の衝突やコンパイラの警告(シャドウ変数)を防ぐために、インスタンス変数にアンダースコアプレフィックスを使用するのが一般的です。

アンダースコアの接頭辞も、インスタンス変数を参照していることを明確にしています。インスタンス変数のためのアンダースコアの接頭辞を使用することにより

、あなたがメソッドの引数にアンダースコアなしで名前を自由に使用している、変数をスタックなど

しかし、プロパティを使用しているとき、あなたは通常はしたくありませんユーザはアンダースコアを書く。

_xインスタンス変数には、通常、xプロパティがあります。あなたが書く理由

これは、次のとおりです。

@synthesize x = _x; 

はのは例を見てみましょう:

@interface Test: NSObject 
{ 
    int x; 
} 

@property(readonly) int x; 

@end 

これは非常に一般的です...しかし、今実装でこれを想像してください:

- (id)initWithX: (int)x 
{} 

私たちは命名の衝突です。

このメソッドの内部では、xはメソッドの引数を参照します。そして、xインスタンス変数にアクセスする方法はありません。

コンパイラの警告フラグによっては、警告(-Wshadow)も発生することがあります。あなたは、インスタンス変数のアンダースコアの接頭辞を使用する場合は

は、すべてが単純である:

- (id)initWithX: (int)x 
{ 
    if((self = [ super init ])) 
    { 
     _x = x; 
    } 

    return self; 
} 

競合しません、ノー命名衝突、... ...ちょうど良い方法を読んで改善

+0

恐ろしい、ありがとう!!!!!これは私が探していた理由の1つで、実際には非常に多くの場合に重要です。 – user1006198

+0

あなたは大歓迎です! :)また、AppleはメソッドのObjCコーディングガイドラインにアンダースコアプレフィックスを使用することを禁じています。インスタンス変数には適用されません。 – Macmade

+0

私はC/C++/Javaや他の言語の背景から、誰かがプロパティとインスタンス変数の違いを知っているとは思わない。はい、私たちは皆インスタンス変数が何であるかを知っていますが、**プロパティ**という言葉はOCの人を除いてよく分かりません:)。 –

9

私はこれを何度も疑問に思いました。他の人の回答に興味がありますが、私が見つけた1つの理由は、getter/setterを使用するときにivarに直接アクセスしている場合に注意することです。

self.myvar = @"blah";myvar = @"blah";

self.myvar = @"blah";_myvar = @"blah";

それは偶然で_を置くために多くの困難です...偶然からself.を残すのは簡単です。

+0

ケニーを置くのが大変です。私はあなたがゲッターとセッターを持っている理由は、直接ivarにアクセスすることを避けることだと考えていませんでした:) – user1006198

1

自己のプロパティを使用している場合、それは「自己」を忘れることは簡単です:

[self.field doSomething]; // what you probably want 
[self setField:someObject]; // also kosher 
self.field = someObject; // ditto, although not my style 

[field doSomething] // might work.. but will bite you eventually 
field = someObject; // almost certainly wrong anywhere outside a custom setter 

プロパティとIVARが、後者の場合は、意志、同じ名前のされている場合苦情なしでコンパイルし、動作しているように見えます。そうしないと、難しい難解なケースが発生します。

ivarの名前が少し異なる場合、末尾に_が追加されていると、コンパイラはあなたを止め、明示的に決定します:ここでプロパティまたはivarを直接参照しますか?

(私は怠け者だとしばしば@synthesize field;を行う、と私は実際に明確なIVARを必要とするとき@synthesize field = field_;と、後でそれを交換、それはカスタムセッター書き込み時間だとき言う、言ったすべてのこと。)

+0

あなたの返信ありがとう! – user1006198