/を使用して「myVariable」を作成する場合、self.myVariable = obj;
との違いは何ですか?myVariable = obj;
@propery
@synthesize
6 に答える
ドット構文は、コンパイラによって単純な objc_msgSend 呼び出しに変換されることに注意することが重要です。つまり、その下では、その変数のアクセサーに送信されるメッセージとまったく同じように機能します。そのため、次の 3 つすべてが同等です。
self.myVariable = obj;
[self setMyVariable:obj];
objc_msgSend(self, @selector(setMyVariable:), obj);
もちろん、これは、ドット構文を使用すると、実際には完全なメッセージが送信されることを意味します。つまり、新しい関数とそれに関連するすべてのオーバーヘッドが呼び出されます。対照的に、単純な割り当て (myVariable = obj;) を使用すると、このオーバーヘッドは発生しませんが、もちろん、問題のクラスのインスタンス メソッド内でのみ使用できます。
@synthesize ディレクティブは、.h ファイルの @property ディレクティブで指定された仕様に従って、メンバー変数のアクセサーを生成するようにコンパイラに指示します。(つまり、retain を指定すると、setter は変数を保持し、copy を指定すると、それをコピーします。)
アクセサーは (特に指定しない限り)、propertyName および setPropertyName という名前になります。
を使用します。記法 (上記の自己構文ではないことに注意してください) は、アクセサーを使用することを示しています (たとえば、文字列を設定していて、保持カウントが正しいことを確認したい場合は良いことです)。
したがって、クラスの実装内で:
- self.bill = fred はアクセサ setBill を呼び出します。
- bill = fred は、アクセサーを経由せずに、bill を fred に直接設定します。
Cocoa 開発を開始したときにわかった違いの 1 つは、変数を @Property/@Synthesize 構文を使用するように設定し、self.myVariable = objまたは[self setMyVariable:obj]を使用せず、代わりに myVariable = objを使用した場合です。 objが後で解放されると、object は保持されません。(保持を使用するように @Property が設定されていると仮定します。)
これは、 myVariable = objを使用すると保持カウントが設定されず、obj が解放されるとカウントがゼロになるためです。(自分で保持しない限り)ただし、アクセサーを使用すると、保持カウントが行われます。(ここでも、宣言されたときに保持を使用するように設定したと仮定します)。
シャイン
これに1つ重要な注意を追加できれば。上記の回答はすべて素晴らしいので、技術的な側面には追加しません。しかし、これだけ:
合成プロパティを作成する場合
@synthesize myProp;
常にself.myPropパターンを使用して設定してください。
self.myProp = newVal;
これは本当に当たり前のようですが、重要です。これを行う理由がないのは事実ですが、合成されたセッターがどのように作成されるかを本当に理解するまでは、自己を使用する必要があると想定したいだけです。値を設定するパターン。
正直なところ、これにより、深夜のデバッグセッションを大幅に節約できます。保持されないメモリ アクセス違反は、デバッグするのが最悪です。
self
構文はアクセサ メソッドを使用しますが、他の構文は使用しません。アクセサーが単に新しい値を割り当てる以上のことを行う場合、これは大きな違いになる可能性があります。Objective-C チュートリアルの宣言されたプロパティの部分を参照してください。
他の答えは正しいです。違いは、ドット表記により ivar が直接ではなくアクセサリを介して変更されることです。
何をしているのかがわかるまでは、ドット表記 (つまりself.propertyName = ...
) を使用することをお勧めします。Cocoa/Obj-C はキーと値のコーディングで多くのことを行います。電話 SDK は (バインディングなどで) それを十分に活用していませんが、最終的にはそうするでしょう。アクセサーの使用に慣れることで、将来の頭痛の種を大幅に減らすことができます。
アクセサー メソッドを使用すると、それらをオーバーライドして、必要に応じてより多くの機能を提供することもできます。ivar の値を変更するだけで、この機能が失われます。