web-dev-qa-db-ja.com

自動プロパティ合成(@property)および継承

XCode 5.1では、新しい警告が表示されます。 -明らかに-何か間違ったことをしていることを理解させてくれました。

アイデアはオブジェクト(モデル)を持つことで、元のクラスから継承する可変バージョンです。したがって、アイデアはreadonlyからreadwriteであったプロパティを開くことです。

@interface Car : NSObject
    @property (strong, readonly) NSString *name;
@end

@interface MutableCar : Car
    @property (strong, readwrite) NSString *name;
@end

それらは別々のファイルにある必要があります(2つの通常のクラスのように)。

そして、それはこの警告を与えます:

Auto property synthesis will not synthesize property 'name' because it is 'readwrite' but it will be synthesized 'readonly' via another property

それが可能であれば、私はそのようなことをするための正しい解決策は何かを知りたいです。アクセサを記述し、自動合成などを使用しないようにする必要がある場合は、ドキュメントなどで正確に答えをサポートしてください。

42
AncAinu

MutableCar実装でプロパティを明示的に合成することをお勧めします。次のように:

@implementation MutableCar

@synthesize name;

@end

そうすれば、clangは autosynthesis を使用しようとしません。

編集:

カプセル化を使用したくない場合、およびその他の理由で親クラスからivarにアクセスする必要がある場合は、もう少し努力する必要があります。

まず、Car .hファイルは同じままです(ivarとプロパティを印刷するためにprintVarメソッドを追加しました)。

@interface Car : NSObject

- (void)printVar;

@property (strong, readonly) NSString *name;

@end

ここで、.mファイルにprintVarメソッドを実装し、clangにセッターを作成するよう指示するクラス拡張を追加しています。

// Private class extension, causes setName: to be created but not exposed.
@interface Car ()

@property (strong, readwrite) NSString *name;

@end

@implementation Car

- (void)printVar
{
    NSLog(@"<Car> Hello %@, ivar: %@", self.name, _name);
}

@end

これで、以前のようにMutableCar.hを作成できます。

@interface MutableCar : Car

@property (strong, readwrite) NSString *name;

@end

mutableCar.mは次のようになります。

@implementation MutableCar

@dynamic name;

- (void)printVar
{
    [super printVar];
    NSLog(@"<MutableCar> Hello %@", self.name);
}

@end

そのようにして、親の_name ivarは実際に親セッターを使用して書き込まれ、アクセスできます。

59
fz.