2014-03-13 11 views
38

Mit XCode 5.1 wird eine neue Warnung angezeigt. Es ließ mich verstehen, -offensichtlich-, dass ich etwas falsch gemacht habe.Auto-Eigenschaftssynthese (@property) und Vererbung

Die Idee war, ein Objekt (ein Modell) zu haben, dessen veränderbare Version von der ursprünglichen Klasse erbt. So ist die Idee, eine Eigenschaft zu öffnen, das war readonly zu readwrite

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

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

Diese Bedürfnisse in separaten Dateien sein (wie zwei normale Klassen).

Und es gibt diese Warnung:

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

So würde Ich mag wissen, was die richtige Lösung ist so etwas wie es zu tun ist, wenn es überhaupt möglich ist. wenn es notwendig ist, Accessoren zu schreiben und Auto-Synthese zu vermeiden, etc. Bitte seien Sie genau und unterstützen Sie Ihre Antwort mit Dokumentation oder was auch immer.

+0

Ich kann die Warnungen mit dem angegebenen Code nicht reproduzieren. – Tim

+0

Ich tat und ja, Sie müssen es in eine separate Datei einfügen, um es zu haben (beide Klassen erstellen) – AncAinu

+0

Jede Flagge, die ich übergeben oder ignorieren könnte, um das loszuwerden? –

Antwort

56

Ich würde vorschlagen, die Eigenschaft in Ihrer MutableCar-Implementierung explizit zu synthetisieren. Wie in:

@implementation MutableCar 

@synthesize name; 

@end 

wird diese Weise Klirren nicht versuchen autosynthesis

bearbeiten zu verwenden:

Wenn Sie nicht wollen, Verkapselung verwenden und aus anderen Gründen müssen Sie die Ivar zuzugreifen die Elternklasse, dann müssen Sie ein wenig mehr Aufwand tun:

Zuerst wird das Auto H-Datei gleich bleibt (ich eine printVar Methode hinzugefügt, um die ivar und Eigentum zu drucken):

@interface Car : NSObject 

- (void)printVar; 

@property (strong, readonly) NSString *name; 

@end 

nun auf der .m-Datei, ich bin der Umsetzung der printVar Methode und auch eine Klassenerweiterung Hinzufügen Klirren zu sagen, die Setter zu erstellen:

// 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 

Jetzt können Sie Ihre MutableCar.h schaffen nach wie vor :

@interface MutableCar : Car 

@property (strong, readwrite) NSString *name; 

@end 

und Ihre MutableCar.m sollte wie folgt aussieht:

@implementation MutableCar 

@dynamic name; 

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

@end 

auf diese Weise die _name ivar auf dem Eltern wird tatsächlich mit dem übergeordneten Setter geschrieben und Sie können darauf zugreifen.

+0

Bedeutet dies einen Unterschied in der Funktionalität oder wird es gleich sein? – AncAinu

+0

Nach der Verwendung, es ist keine gute Antwort, es ist genau und entfernen Sie die Warnung, aber es ändert sich die Art, wie es funktioniert, da es eine neue iVar in der Kindklasse erstellt, anstatt die Eltern wie es geschützt ist. – AncAinu

+0

@anc Kannst du mir deinen genauen Fall zeigen ?. Haben Sie einen bestimmten Ivar für diese Eigenschaft ?. Dieser Fall sollte funktionieren, siehe folgendes Beispiel: https://gist.github.com/Reflejo/11c91b929bf021308b95 –