1

特に達成したいことはありませんが、クラス拡張についてもっと学びたいと思っています。

これは、アップルのカテゴリと拡張から直接クラス拡張の説明です:

@interface MyClass : NSObject
@property (retain, readonly) float value;
@end

// Private extension, typically hidden in the main implementation file.
@interface MyClass ()
@property (retain, readwrite) float value;
@end

ただし、MyClass を拡張する MyClass2 があると仮定すると、それは私には完全に理にかなっています。

@interface MyClass2 : MyClass
@property (retain, readwrite) float value;
@end

クラス拡張が関係していなければ、簡単に答えることができるいくつかの質問があります。

  • 実行時に、MyClassで割り当てself.value=2を行っているとき、または単にfloat x=self.valueを呼び出しているときに、どのセッターとゲッター @property が呼び出されますか? MyClass または MyClass2 ?
  • コンパイラは、少なくとも読み取り専用プロパティが再定義されているという警告を発行するべきではありませんか?
  • @property が ivar によってサポートされていることは知っていますが、最終的にいくつの ivar があるのでしょうか? これに関連して、ivarが設定するMyClass2の観点から同じ self.value を呼び出しますか?
4

2 に答える 2

1

まず、プロパティはスカラー型であるため、「保持」ではなく「割り当て」である必要があります。

クラス エクステンションまたはサブクラスでの書き込み可能性の変更は、パブリックには読み取り専用だがプライベートには書き込み可能なプロパティと、不変クラスの可変サブクラスをそれぞれ実装する一般的なパターンです。Apple Objective-C Programming Guide には、良い議論があります。

最初の質問に答えると、MyClass またはそのスーパークラスで宣言されたメソッドのみが MyClass 内から表示されます。プライベート クラス エクステンションは、実装のスコープ内でセッターを宣言するため、それが呼び出されます。MyClass2 のインターフェイスでの readwrite 宣言は、setter を public スコープに入れるだけです。実装はまだ MyClass にあります。

2 番目の質問に対する答えはノーです。警告は発行されません。書き込み可能を読み取り専用から読み書き可能に変更することは有効です。

最後に、ivar は 1 つだけです。MyClass2 からアクセスすると、MyClass に表示される同じ ivar に影響します。

于 2012-11-22T17:53:51.453 に答える
0

できませんretain。代わりにfloat書きましょう。(readonly)

MyClassMyClass2のサブクラスと思われるについて何も知りませんMyClass。と書くself.value = 2と に変換され[self setValue:2]、コードは MyClass から始まり、メソッドを探しますsetValue。プロパティとして定義したため、これが作成さvalueれます。セッターメソッドは次のようになります

-(void) setValue:(int newValue) {
      _value = newValue; // _value is the actual storage for the property value
}

変数は、実行中_valueのオブジェクトのインスタンスに割り当てられたものになります。MyClass

実際、iVar は 1 つだけです。でMyClass2、あなたが書く場合

self.value = 3;
super.value = 4;
float myFloat = self.value;

myFloat最終的には 4 になります。

おそらくコンパイラは、プロパティの再定義について不平を言うことはありませMyClassん。これは、非常に合理的なことだからです。そうすれば、他のクラスは に書き込むことはできませんvalueが、 内MyClassでは書き込むことができ、self.value = 2;機能します。

2 つの iVar があると信じていましたが、それは間違いでした。混乱させてごめんなさい。私を教育してくれた Martin R と BradS に感謝します。

于 2012-11-22T17:20:28.577 に答える