21

最新 (64 ビット OS X および iPhone OS) の Objective C ランタイムの機能の 1 つは、クラスで明示的に宣言せずに ivar を動的に合成するプロパティの機能です。

@interface MyClass : NSObject {
//  NSString *name; unnecessary on modern runtimes
}

@property (retain) NSStrng *name;

@end

@implementation MyClass

@synthesize name;

@end

私のコードのかなりの部分で、プロパティを初期化するためにカスタム getter 実装を使用しています。

- (NSString *) name {
  if (!name) {
    name = @"Louis";
  }

  return name;
}

上記は、ヘッダーで宣言されていないivarにアクセスする必要があるため、合成されたivarと互換性がありません。さまざまな理由から、最新のランタイムでビルドするときに合成 ivar を使用するように多くの個人的なフレームワークを更新したいと考えています。その目標を達成するには、合成 ivar で動作するように上記のコードを変更する必要があります。

Objective C 2.0 のドキュメントには、最新のランタイムで合成されたアクセサーが最初の使用時に ivar を合成すると記載されています。これを行うために使用される低レベルのメカニズムは指定されていません。それは class_getInstanceVariable() によって行われますか、class_addIvar() の制限は緩和されますか、それは目的の C 2.0 ランタイムで文書化されていない関数ですか? プロパティをサポートするデータ用に独自のサイド ストレージを実装することもできますが、合成されたアクセサーが使用しているメカニズムを使用したいと思います。

4

3 に答える 3

20

先ほどドキュメントをもう一度見ましたが、読み間違えているようです。合成された ivar は、実行時ではなくコンパイル時に作成されます。

Objective-C 2.0のドキュメントによると:

ランタイムに依存する動作には違いがあります (「ランタイムの違い」も参照してください)。

従来のランタイムの場合、インスタンス変数は @interface ブロックで既に宣言されている必要があります。プロパティと同じ名前で互換性のある型のインスタンス変数が存在する場合は、それが使用されます。そうでない場合は、コンパイラ エラーが発生します。

最新のランタイムでは、インスタンス変数は必要に応じて合成されます。同じ名前のインスタンス変数が既に存在する場合は、それが使用されます。

したがって、必要なインスタンス変数を宣言するだけで、同じコードが両方のランタイムで機能します...

于 2008-11-08T20:17:31.217 に答える
0

探しているのは、次のような @synthesized 名です。

@synthesize name = _name;

...

- (NSString *) name {
    if (!name) {
        _name = @"Louis";
    }

    return _name;
}
于 2012-01-28T13:51:50.457 に答える
-6

NSKeyValueCoding Protocolを使用して実行時にプロパティを追加します。

[myObject setValue:@"whatever" forKey:@"foo"];
于 2011-04-04T18:49:44.243 に答える