web-dev-qa-db-ja.com

プロパティの継承:自動プロパティ合成はプロパティを合成しません

要約

この質問は、プロパティを継承するクラスの内部および外部からのさまざまな読み取り/書き込みアクセスと組み合わせたプロパティの継承についてです。

詳細

1つのクラスAと、Bから継承する別のクラスAがあります。プロパティsomePropertyAで宣言されています。プロパティをこれらのクラスの外部からは読み取り専用にし、内部からは読み取り/書き込みを許可します。

クラスが1つだけの場合、これは非常に単純です。.hでプロパティを読み取り専用として宣言し、カテゴリ内の.mで再度読み取り/書き込みとして宣言します。できました。

しかし、一方が他方から派生している2つのクラスを使用すると、Bに以下のコンパイラ警告が表示されます。

自動プロパティ合成では、プロパティ 'someProperty'は合成されません。これは 'readwrite'であるため、別のプロパティを介して 'readonly'が合成されるためです。

これがコードです:

A.h:

#import <Foundation/Foundation.h>

@interface A : NSObject

// This property shall be readonly from outside, but read/write from subclasses
@property (readonly) SInt32 someProperty;

@end

午前:

#import "A.h"

@implementation A
@end

B.h:

#import <Foundation/Foundation.h>
#import "A.h"

@interface B : A

@end

午前:

#import "B.h"    

@interface B ()

// compiler warning in the following property declaration:
// /Users/.../B.m:12:41: Auto property synthesis will not synthesize property
// 'someProperty' because it is 'readwrite' but it will be synthesized
// 'readonly' via another property
@property (readwrite) SInt32 someProperty;

@end

@implementation B
@end

この警告が表示されるのはなぜですか?それを回避するためにコードをどのように構成する必要がありますか?

16
Daniel S.

プロパティを所有クラス(A)で読み取り/書き込みとして宣言し、サブクラス(B)で再宣言して、コンパイラーがそのプロパティを使用することを認識させる必要があります。したがって、Aはアクセサメソッドをホストし、Bはそれを使用します。通常、Bに別のアクセサメソッドを作成させたくないので、@dynamicを使用して、スーパークラス(技術的には別のクラスのみ)が実装を提供することをコンパイラに通知できます。

A。mのBでカテゴリ(拡張子ではなく)を宣言することもできます。これにより、アクセサメソッドを明示的に宣言します(プロパティを使用せず、メソッドのみ)。 '実際に興味があります(プロパティが指定する他のことは実際には必要なく、スーパーとサブクラスでプロパティ属性が確実に一致するようにするためのメンテナンスオーバーヘッドも必要ありません)...

10
Wain