5

重複の可能性:
カカオのobjective-cクラスの変数の前にあるアンダースコアはどのように機能しますか?

だから私はあなたがプロパティを合成するときにアンダースコアを使わなければならないことを知りました、そしてそれは私には少しも意味がありません。

それでは、始めましょう。.hファイルに次の行を記述します。

@property (nonatomic) double speed;

.mファイルでは、次のようにします。

@synthesize speed = _speed;

なんで?私の知る限り、プロパティはインスタンス変数を作成し、そのためのセッターとゲッターを作成します。しかし、何が起こっているのか

@synthesize speed = _speed 

行う?常識的に言うと、速度には_speedの値を割り当てます。わかった。どこで_speedを宣言しましたか?コンパイラがエラーを出さないのはなぜですか?それはどういう意味ですか?なぜそのような難読化されたコードなのか?

ここでの私の質問:

私がただやったらどうなりますか

@synthesize speed;

_speedがないと、エラーやバグが発生しますか?この構文の後の理由は何ですか?彼らはそれを作るときに何を考えていましたか?_speedはどこから来るのですか?それは何ですか?それはポインタですか、それとも実際の値ですか?何が起こっている?

4

7 に答える 7

5

さて、_speedプロパティによって使用されるインスタンス変数です。本当に完全に宣言したい場合は、次のように書く必要があります。

@interface Foo
{
    double _speed;
}

@property double speed;

@end

@implementation Foo

@synthetize speed = _speed;

@end

これでXcode4.4が解き放たれました。そのほとんどは不要であり、健全性のために省略する必要があります。

基本的に、あなたがしなければならないのは:

@interface Foo

@property double speed;

@end

インスタンス変数も、もありません@synthetize。すべてが以前と同じように機能します。self.speedまたはself->_speed直接アクセスに使用できます。

于 2012-07-12T19:42:18.713 に答える
1

さて、これを行う必要はありません...

ただし、そうすることで、実装でそのプロパティのアンダースコア以外の名前を使用できないことを意味します。実際、そうすることで、プロパティを介してではなく、iVarに直接アクセスすることに混乱するためです。

つまり、これを行うことによって:

@synthesize myProperty;

コードでは、myPropertyiVar)またはself.myProperty(プロパティ-アクセスルール-読み取り専用/読み取り/書き込み、ゲッター、セッターなど)で参照できます。もちろん、次のようなルールを使用している場合、これは混乱を招く可能性があります。

@property(nonatomic, retain, getter = anotherProperty) NSNumber myProperty

コード内でこれにアクセスすることによりmyProperty、次の値を取得することが期待されますanotherProperty

これは、次のことを行うことによってのみ可能になります。

self.myProperty

したがって、Objective-Cでは、これを回避するために次のことを実行できます。

@synthesize myProperty = _myProperty;

したがって、コードでは、直接参照することは実際にはエラーであり、代わりに(プロパティアクセス)または(iVarアクセス​​)myPropertyを実行する必要があります。self.myProperty_myProperty

于 2012-07-12T19:41:32.663 に答える
1

あなたはそれをする必要はありません。それはただの一般的な習慣です。... = _ speedは_speedという名前のプロパティを作成し、そのsetterとgetterはspeedにちなんで名付けられます。それはあなたが区別することを可能にします

self.speed = value;

speed = value; 

後者はコンパイラエラーを作成するためです。

_speed = value; 

その場合は正しいでしょう。

セッターはオブジェクトを保持し、単純な担当者は保持しないため、これは保持/解放関連のエラーを回避するのに役立ちます。(self.speed = ...セッターを呼び出します!)

合成ステートメントで「=_speed」を省略すると、プロパティの名前は「speed」のみになります。間違いをしなければ、これは完全にうまくいきます。

于 2012-07-12T19:42:18.313 に答える
0

その命名規則、あなたはそれする必要はありません。人々は、インスタンス変数とプロパティを区別できるようにこれを行う傾向があります。

通常それは行きます

.h

@interface myClass : NSObject
{
    NSNumber *_speed
}

@property (nonatomic, strong) NSNumber *speed;

.m

@implementation
@syntesize speed = _speed;
于 2012-07-12T19:41:43.387 に答える
0

悪いことは何も起こりません-@synthesizespeedと書くだけで問題ありません。_speedを使用すると、基になるインスタンスがspeedではなく_speedになります。ほとんどの人は、thr getterを介してではなく、誤ってivarに直接アクセスしないようにするためにこれを行います。

于 2012-07-12T19:41:54.160 に答える
0

ドキュメントから

@synthesize speed = _speed;プロパティspeedがインスタンス変数を指すようになります_speed

これを行う必要はありませ@synthesize speedうまく動作します。

于 2012-07-12T19:57:11.940 に答える
0

手動メモリ管理のある環境:

インスタンス変数名が必要なのはなぜですか?

  1. あなたはdeallocのあなたのプロパティによって使用されるかもしれないメモリを解放する必要があります
  2. 使用できますself.field = nilが、このアプローチは問題を引き起こす可能性があります
  3. [_field release];したがって、deallocで使用できるように、このプロパティの背後で使用されるインスタンス変数が必要です。

イニシャライザでプロパティにアクセスする必要がある場合も同じです。

インスタンス変数名にアンダースコアが必要なのはなぜですか?

  • 誤ってivarを直接使用したり、プロパティのメモリ管理契約を破ったりしないようにする

@property (retain) UILabel *label;

...

@synthesize label;

...

-(void)viewDidLoad {
   [super viewDidLoad];

   label = [[[UILabel alloc] initWithFrame:frame] autorelease];
}

ここで誤って自己を失った。あなたはlabel潜在的な「ダングリングポインタ」を作りました。上記のコードを使用@synthesize label = _label;すると、コンパイラエラーが発生します。

  • ローカル変数またはメソッドパラメータ名は、多くの場合、プロパティ名と同じになる傾向があります。下線付きのインスタンス変数を使用しても、問題は発生しません。
于 2012-07-12T20:15:37.103 に答える