17

Xcodeで分割ビューアプリケーションを選択すると作成される標準のサンプル分割ビューで遊んでいました。いくつかのフィールドを追加した後、詳細ビューに表示するためにいくつかのフィールドを追加する必要がありました。

元のサンプルで何か面白いことが起こった場合、マスタービューは詳細ビューに「detailItem」プロパティを設定し、詳細ビューはそれを表示します。

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

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

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

しかし、私が使用したとき

self.detailItem != newDetailItem

私は実際にこのメソッドが絶えず呼び出されるループで立ち往生していて、シミュレーターで他に何もできません。

私の質問は、アンダースコア変数(ivar?)とプロパティの実際の違いは何ですか?私はここでいくつかの投稿を読みましたが、それは単なる客観的なCの慣習のようですが、実際にはいくつかの違いがありました。

4

4 に答える 4

41

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

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

あなたの場合、setterメソッドでそれを呼び出し、再帰呼び出しを作成します。

于 2012-12-08T11:02:08.330 に答える
6

実験の過程で、無限ループを設定しました。これが、シミュレーターが応答しなくなる理由です。

クラスはプロパティのカスタムセッターメソッドを実装しているため、呼び出しのスコープ内で再帰的self.detailItemsetDetailItem:呼び出す。setDetailItem:detailItem

プロパティ、ivarなどのスクープの宣言されたプロパティに関するAppleのドキュメントを参照してください。ただし、簡単に言うと、宣言されたプロパティは、クラスにアクセサーメソッドを提供する簡単な方法です。独自のアクセサメソッドを作成する必要はなく(Objective-C 2.0より前に作成する必要がありました)、プロパティ構文を介して生成されるようになりました。

于 2012-12-08T11:01:57.287 に答える
5

プロパティは基本的に、コンパイラが特定のインスタンス変数のセッターゲッターを生成する方法です。

したがって、次のようなものを使用する場合:

id detailItem = self.detailItem;

内部で行っていることは次のとおりです。

id detailItem = [self detailItem];

同じ:

self.detailItem = otherDetailItem;

だろう:

[self setDetailItem:otherDetailItem];

したがって、セッターを自分で作成すると、メソッド自体にアクセスするため、無限ループに陥ります。「自分」を自由に活用できます。上記のメカニズムのために、セッターまたはアクセサーをオーバーライドする場合ではなく、クラスでの表記。

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

于 2012-12-08T11:01:57.617 に答える
2

例を示します(ARCを有効にしないで):

@property (nonatomic, retain) NSNumber* number;

合成しない場合は、次の方法でアクセスできます。

self.number= [NSNumber numberWithBool: YES];

この場合、番号は保持されます。代わりにそれを合成し、プロパティを使用しない場合:

@synthesize number;

ファイルの後半:

number=[NSNUmber numberWithBool: YES];

プロパティを使用していないため、番号は保持されません。これにより、アクセサと合成プロパティの使用に関連する違いが生じます。

于 2012-12-08T13:02:57.983 に答える