Überschreiben einer readonly-Eigenschaft in der Unterklasse

Gibt es eine Klasse, die wie folgt aussieht (ich bin Wegfall der Importe aus Platzgründen):

Basis.h:

@interface Base : NSObject
@property (strong, readonly) NSString *something;
- (id)initWithSomething:(NSString *)something;
@end

Basis.m:

@implementation Base
- (id)initWithSomething:(NSString *)something {
    self = [super init];
    if (self) _something = something;
    return self;
}
@end

Als Sie sehen, die 'etwas' Eigenschaft readonly ist. Jetzt will ich erstellen Sie eine Unterklasse überschreibt die Eigenschaft beschrieben werden als gut:

Sub.h:

@interface Sub : Base
@property (strong) NSString *something;
@end

Sub.m:

@implementation Sub
@end

Und den code:

main.c:

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Sub *o = [Sub new];
        o.something = @"foo";
        NSLog(@"%@", o.something);
    }
    return 0;
}

Dieser code führt zu:

    2013-09-07 13:58:36.970 ClilTest[3094:303] *** Terminating app due to uncaught
    exception 'NSInvalidArgumentException', reason: '-[Sub setSomething:]: unrecognized
    selector sent to instance 0x100109ff0'

Warum ist das so? Warum nicht, es finden die setSelector?

Wenn ich das in der Unterklasse statt:

Sub.m:

@implementation Sub
@synthesize something = _something;
@end

alles funktioniert. Bedeutet das, dass die Unterklasse' - Eigenschaft wird nicht synthetisiert standardmäßig, obwohl es ist definiert als @property im @interface? Funktioniert das kompilieren irgendwie "sehen" die automatisch erzeugten getter von der Basis und nicht erzeugen die setter? Und warum, ich denke, der setter erzeugt werden sollen, als es noch nicht existiert. Ich bin mit Xcode 4.6.2 und das Projekt ist ein Cli-Tool (Typ-Stiftung), aber das gleiche passiert auch in meinem aktuellen Projekt ist eine iPhone-app.

Hintergrund: ich habe ein schweres Objekt (eine Instanz der Basis), erfordert eine Bluetooth-Verbindung zu einigen Geräten und ich sollte das erstellen einer view-controller für einige Funktionen. Für einfache Tests möchte ich nicht angeschlossen werden, um BT (eigentlich bräuchte ich ein physisches Gerät und testen Sie den code drauf), ich möchte in der Lage sein, um es zu testen im simulator.
Was ich mir ausgedacht habe ist, dass ich Sie einfach erstellen Sie eine Unterklasse (Sub), die stubs ein paar Eigenschaften /Methoden und verwenden Sie stattdessen, und wenn der code fertig ist, ich entfernen Sie einfach den code für die Unterklasse, ersetzen Sie die Instanz mit dem richtigen, im test mit einem Gerät, commit und push. Es funktioniert eigentlich einwandfrei, bis auf die seltsame Sache mit @property oben.

Könnte jemand mir sagen, was Los ist mit der Eigenschaft überschreiben?

  • Neben der Lösung arbeiten, ich wollte noch hinzufügen, dass 'die Erhöhung' der Ebene der Privatsphäre ein Attribut geht gegen die OOP-Prinzipien. In der Regel (aber nicht immer), wenn Sie haben, um eine Immobilie mehr sichtbar (privat -> protected oder protected -> öffentlich) in einer Unterklasse, dann ist etwas falsch in das Modell. Das Gegenteil geschieht mit den Methoden. Wenn die übergeordnete Klasse hat Eine Methode, Sie sollten nicht machen Eine private (public -> protected oder protected -> privat) in einer Unterklasse.
InformationsquelleAutor wujek | 2013-09-07
Schreibe einen Kommentar