2012-12-08 10 views
15

Xcodeで分割ビューアプリケーションを選択したときに作成される標準のサンプル分割ビューを使用していましたが、いくつかのフィールドを追加した後、詳細ビューで表示されます。目的Cアンダースコアプロパティvs自己

オリジナルのサンプルでは何か面白いことがありますが、マスタービューでは詳細ビューに「detailItem」プロパティが設定され、詳細ビューに表示されます。

- (void)setDetailItem:(id) newDetailItem 
{ 
if (_detailItem != newDetailItem) { 
    _detailItem = newDetailItem; 

    // Update the view. 
    [self configureView]; 
} 

私はそれが何であるかを理解しているので、私はそれを周りに遊んでいました。私はself.detailItemを使用して_detailItemの代わりにそれが同じであると思った、それはクラスのプロパティだから。私は

self.detailItem != newDetailItem 

を使用する場合

しかし、私は実際にこのメソッドが常に呼び出されたループに陥ってしまったと私はシミュレータで何かをやる傾けます。

私の質問は、アンダースコア変数(ivar?)とプロパティの実際の違いは何ですか? 私はいくつかの記事をここで読んでいますが、それはちょうどいくつかの客観的なCのコンベンションであるようですが、実際にはいくつかの違いがありました。

答えて

6

あなたの実験の途中で、シミュレータが応答しなくなる理由である無限ループを設定しました。

あなたのクラスは、プロパティdetailItemのカスタムsetterメソッドを実装しているのでsetDetailItem:呼び出しを再帰的setDetailItem:の範囲内self.detailItemを呼び出します。

プロパティ、ivarsなどのスクープの宣言されたプロパティについては、Apple documentationを参照してください。簡単に言えば、宣言されたプロパティは、クラスのアクセサメソッドを提供する簡単な方法です。 Objective-C 2.0以前のように、独自のアクセサメソッドを記述するのではなく、プロパティ構文で生成​​されます。

+0

ああ、このような明白な間違い。ありがとうalot – Pita

+0

ありがとう! – cp3

5

プロパティは基本的に、与えられたインスタンス変数に対してセッターゲッターを生成するためのコンパイラーの方法です。あなたはボンネットの下に何をしているか

id detailItem = self.detailItem; 

されています:

id detailItem = [self detailItem]; 

同じのために:

self.detailItem = otherDetailItem; 

は次のようになります。

は、だから、のようなものを使用する場合

[self setDetailItem:otherDetailItem]; 

それで、あなた自身でsetterを書くと、メソッド自体にアクセスするので無限ループに陥ります。 「自己」を自由に利用することができます。あなたのクラスの表記法は、私が上で説明したメカニズムのためにセッターやアクセサーをオーバーライドしているときにだけではありません。

私が使用するクラスのケース。単純にivarにアクセスするという表記法は、値を変更するときには、値を変更するときに何が起こる必要があるのか​​をクラス内では決して知りません。一部の代表者にステータスが変更されたことを通知する必要があるステータスに関して何かを持っていますか?しかし、通常はこれを使用するだけではありません。あなたがセッターメソッドでいくつかの魔法をすることにしたなら、将来的にはコードをリファクタリングする必要がないことを確認しています。

39

_propertyは、このプロパティに直接アクセスしていることを意味します。

self.propertyは、アクセサを使用していることを意味します。

あなたのケースでは、setterメソッドでこれを呼び出して再帰呼び出しを作成します。私は(ARCが有効なし)の例を作ってあげる

2

@property (nonatomic, retain) NSNumber* number; 

あなたがそれを合成しない場合、あなたはこのようにそれをアクセスすることができます。

self.number= [NSNumber numberWithBool: YES]; 

この場合の数でありますretained.If代わりに、あなたはそれを合成し、プロパティを使用しないでください:

@synthesize number; 

以降のファイルで:

number=[NSNUmber numberWithBool: YES]; 

あなたはプロパティを使用していないので、番号は保持されません。これはアクセサと合成プロパティの使用に適切な違いをもたらします。