1

Apple は、クラスを初期化するときに、getter/setter を使用するのではなく、プロパティを直接サポートするインスタンス変数にアクセスすることをお勧めします。

https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html

ただし、親クラスのプロパティをサポートするインスタンス変数は、子クラスではアクセスできないようです。これはなぜですか?すべてのインスタンス変数が親クラスの init 関数で初期化されていないライブラリ (Cocos2d) でクラスを拡張しています。例えば:

---

@interface parentClass

@property (assign) int myProperty;

----

@interface childClass : parentClass

----

@implementation childClass

- (id) init {
  // this doesn't work.
  _myProperty = 0;
}
4

2 に答える 2

2

サブクラスのスーパークラスからインスタンス変数にアクセスすることはできないため、これ_variableNameも機能しません。

initメソッドは次のようになります

- (instancetype)init {
    if (self=[super init]) {
        // subclass initialisation goes here
    }
}

オブジェクトが[super init]返されると、オブジェクトのスーパークラス部分が初期化されるため、getter と setter を使用してプロパティに安全にアクセスできるはずです。

- (instancetype)init {
    if (self=[super init]) {
        self.superClassProperty = aValue;
    }
}

インスタンス変数を使用するタイミングとメソッド (プロパティ アクセサーなど) を呼び出すタイミングについては、QualityCoding の「Objective-C init で自己にメッセージを送信しない」を参照してください。要するに、オブジェクトが一貫した状態にある場合にのみメソッドを呼び出してください。

バッキング ivar にアクセスできないのはなぜですか?

ヘッダー内のプロパティ宣言は、プロパティのゲッターとセッターを宣言します。バッキング ivar は、実装で発生するプロパティの合成時に作成されます。(自動合成と手動合成では違いはありません)。そのため、ivar 宣言は実装でのみ表示されます。サブクラスの ivar に絶対にアクセスする必要がある場合は、それらを公開する必要があります (または、サブクラス化専用のヘッダーに入れて半公開にする必要があります)。

于 2013-09-10T00:59:14.100 に答える
0

parentClass.h で次のことができます。

@interface parentClass {
  @protected
  int _myProperty;
}
@property (nonatomic) int myProperty;

次に、あなたの childClass.m で

- (instancetype)init {
    if (self=[super init]) {
        _myProperty = aValue;
    }
}

iVar はデフォルトで保護されていると宣言されているため、子供はそれらを見ることができます。@protected と書く必要はありません。参考までに、それらを @private または @public として宣言することもできます。

ただし、parentClass.m のプライベート インターフェイスに保護された iVar を記述した場合、これは機能せず、子には表示されません。

于 2016-01-29T13:44:43.327 に答える