82

Objective-Cでivarとプロパティを使用するこれらの3つの方法の意味上の違いは何ですか?

1.1。

@class MyOtherObject; 
@interface MyObject {
}
@property (nonatomic, retain) MyOtherObject *otherObj;

2.2。

#import "MyOtherObject.h"
@interface MyObject {
    MyOtherObject *otherObj;
}
@property (nonatomic, retain) MyOtherObject *otherObj;

3.3。

#import "MyOtherObject.h"
@interface MyObject {
    MyOtherObject *otherObj;
}
4

2 に答える 2

57

番号 1は、 MyOtherObject クラスを前方宣言して、コンパイラとリンカによって表示されるコードの量を最小限に抑え、循環参照を回避する可能性があるという点で、他の 2 つとは異なります。この方法で行う場合は、#import を .m ファイルに入れることを忘れないでください。

@property (および .m の @synthesize と一致する) ファイルを宣言することにより、指定した方法で処理されるメモリ セマンティクスを使用してアクセサー メソッドを自動生成します。ほとんどのオブジェクトの経験則は Retain ですが、たとえば NSStrings は Copy を使用する必要があります。通常、シングルトンとデリゲートは割り当てを使用する必要があります。手書きのアクセサーは面倒でエラーが発生しやすいため、多くのタイピングやばかげたバグを省くことができます。

また、合成されたプロパティを宣言すると、次のようにドット表記を使用してアクセサー メソッドを呼び出すことができます。

self.otherObj = someOtherNewObject; // set it  
MyOtherObject *thingee = self.otherObj; // get it 

通常のメッセージパッシング方法の代わりに:

[self setOtherObject:someOtherNewObject]; // set it
MyOtherObject *thingee = [self otherObj]; // get it 

舞台裏では、次のようなメソッドを実際に呼び出しています。

- (void) setOtherObj:(MyOtherObject *)anOtherObject {

    if (otherObject == anOtherObject) {
        return;  
    }

    MyOtherObject *oldOtherObject = otherObject; // keep a reference to the old value for a second
    otherObject = [anOtherObject retain]; // put the new value in  
    [oldOtherObject release]; // let go of the old object
} // set it

…またはこれ

- (MyOtherObject *) otherObject {  
    return otherObject;
} // get it

お尻の完全な痛み、右。クラス内のすべてのivarに対してこれを行います。正確に行わないと、メモリ リークが発生します。コンパイラに作業を任せるのが最善です。

Number 1には ivar がありません。これはタイプミスではないと仮定すると、 @property / @synthesize ディレクティブが舞台裏で ivar も宣言するので問題ありません。これは、Mac OS X - Snow Leopard および iOS4 の新機能だと思います。

番号 3にはこれらのアクセサーが生成されていないため、自分で作成する必要があります。アクセサー メソッドに副作用を持たせたい場合は、上記のように標準的なメモリ管理ダンスを実行してから、必要な副次的な作業をアクセサー メソッド内で実行します。プロパティを合成するだけでなく、独自の を作成する場合バージョンが優先されます。

私はすべてをカバーしましたか?

于 2010-11-13T15:21:37.623 に答える
17

昔はivarがあり、他のクラスにそれらを設定または読み取らせたい場合は、ゲッター(つまり、-(NSString *)foo)セッター-(void)setFoo:(NSString *)aFoo;)を定義する必要がありました。

プロパティが提供するのは、ivarと一緒に(ほぼ!)無料のセッターとゲッターです。したがって、ここでプロパティを定義するときに、アトミック性(たとえば、複数のスレッドからの複数の設定アクションを許可するかどうか)と、セマンティクスの割り当て/保持/コピー(つまり、セッターが新しい値をコピーする必要があるかどうか)を設定できます。または、現在の値を保存するだけです。別のクラスが、後で変更される可能性のある可変文字列を使用して文字列プロパティを設定しようとしている場合に重要です)。

これが何をするか@synthesizeです。多くの人がivar名を同じままにしますが、synthezeステートメントを作成するときに変更できます(つまり、プロパティに@synthesize foo=_foo;名前を付けたivarを作成することを意味します。したがって、このプロパティを読み書きする場合は、を使用しません。使用する必要があります-セッターとゲッターのみを通過したい場合は、ivarへの直接参照をキャッチするのに役立ちます)。_foofooself.foo_foo = ...

Xcode 4.6以降では、ステートメントを使用する必要はありません@synthesize。コンパイラーはこれを自動的に実行し、デフォルトではivarの名前の前に。を付け_ます。

于 2012-08-05T19:49:12.413 に答える