4

最新の Objective-C ランタイムでは、次のようなことができます。

@interface MyClass : NSObject {
}
@property NSString *stringProperty;
@end

@implementation MyClass
@synthesize stringProperty;
@end

これは、プロパティのアクセサーを合成するだけでなく、インスタンス変数自体も合成するため、このクラスのメソッドの1つで言うことができ[stringProperty length];、インスタンスを宣言したかのように機能します変数。

私は今、すべてのコードでこれを使い始めました。なぜなら、何度も何度も書かなければならないことが 1 つ減ったからです。そして、clang 2.0 コンパイラで、スキップすることさえできると聞いたことがあります@synthesize(ただし、それは別の問題です)。しかし、私は疑問に思っていました、これを行うことの欠点は何ですか? プロパティに加えてインスタンス変数が本当に必要になるのはいつですか?

変数をプライベートに保ち、外部からのアクセスを許可したくない場合があることはわかっています (ただし、通常は、プライベート クラス拡張でプロパティを宣言するか、プロパティをまったく作成しません。アクセサは必要ありません)。

これをしたくないときはありますか?

4

5 に答える 5

4

合成されたインスタンス変数を使用しない方がよい理由の 1 つは、現在のバージョンの Xcode (3.2.5) でデバッグするのが少し面倒だからです。GDB を介してコードを実行している場合、これらはライブ デバッガー ビューに表示されないようです。それらを取得する唯一の方法は、po [0xOBJ_ADDRESS propertyName]. 標準の合成されていない ivar ほど良くはありません。

おそらく Xcode 4 でこれが修正されるかもしれませんが、私はそれについて言うのに十分な経験がありません (そして、まだ NDA の下にあります)。

この SO の質問の詳細:バッキング変数がない場合、Xcode デバッガーで合成されたプロパティの値を見る

于 2010-12-07T21:23:02.270 に答える
3

単一のインスタンス変数に多くのプロパティを提供したい場合があります。たとえば、次のようになります。

  • 度とラジアンの両方で角度値にアクセスするため
  • 直交座標系と極座標系の両方で座標にアクセスするため

このような場合、インスタンス変数 (既に存在する) やアクセサー メソッド (変換を行うためにそれらを提供したい) を合成したくありません。

于 2010-12-07T21:01:31.427 に答える
1

しかし、私は疑問に思っていました、これを行うことの欠点のいくつかは何ですか?プロパティに加えて、インスタンス変数が本当に必要になるのはいつですか?

考えられる理由:

  • これにより、サブクラスオーバーライドまたはKVOをトリップすることなく、インスタンス変数initを変更できます。dealloc
  • アプリはMacOSX上で32ビットモードでコンパイルおよび実行されます。64ビットをサポートしていないIntelMacがまだいくつかあります。

最初のポイントが実際にどれほど有効かはわかりません。問題を回避する他の方法があるかもしれません。2つ目のポイントは、古いMacをサポートする必要がある場合は、ゲームオーバーです。

于 2010-12-08T11:43:12.470 に答える
1

クラスで変換を行う必要があるときはいつでも(誰かがより良い方法を知っていない限り)、シリアル化する必要があります。たとえば、数値を持つクラスがあるとします。整数をシリアル化できないため、クラスに NSNumber として格納しますが、プロパティは整数型です。

もう 1 つの例は、CoreData を使用するときに Apple が推奨するようにコーディングする場合です。彼らは、管理対象オブジェクトのクラスとして NSManagedObject から派生したカスタム クラスを作成し、各属性のプロパティを使用する必要があると言います。次に、@synthesize の代わりに @dynamic を使用し、iVar はまったく必要ありません。

于 2010-12-07T21:10:52.983 に答える
0

もう 1 つの理由は、直接変数にアクセスするためのショートカットを避けることです。

私は個人的なコーディング規約に従うようにしています: - オブジェクト変数: アンダースコア '_xxx' の接頭辞 - プロパティ: アンダースコア 'xxx' なしの名前

これにより、意図せずに次のようなことを書くことがなくなります

xxx = value;

また

[xxx someMessage];

常にゲッター/セッターを使用したい。

self.xxx = value;
[self.xxx someMessage];

これは、オブジェクト変数に遅延初期化を使用している場合に特に便利です...

于 2010-12-08T09:48:04.820 に答える