2012-04-13 8 views
1

Dies ist mein erster Beitrag; Diese Site war eine unschätzbare Ressource.Erben Accessoren in Objective-C

Ich bin ziemlich neu zu objective-c so bitte mit.

Also habe ich eine Basisklasse mit ein paar Eigenschaften, die ich "privat" will, also habe ich sie nur gelesen. Um es klar zu sagen, ich möchte nicht, dass sie extern veränderlich sind, aber ich möchte den 'set' Accessor in dieser Klasse verwenden. So ...

// .h file 
@interface Vehicle 
@property (nonatomic, readonly) int speed; 
@end 

Auch wiederholte ich die Eigenschaft Erklärung innerhalb einer Kategorie Interface-Block die Accessoren in dieser Klasse beschreibbar zu machen

// .m file 
//Private properties and methods 
@interface Vehicle() 
@property (nonatomic, readwrite) int speed; 
@end 

@implementation 
@synthesize speed = _speed; 
- (void) someMethod { 
    [self setSpeed:10]; // Works fine 
} 

@end 

Aber jetzt, wenn ich diese Klasse erben die abgeleitete Klasse nicht mehr hat die Set-Accessor-Methode (setSpeed ​​in meinem Fall). Muss ich wieder synthetisieren? Es scheint, als würde das den Zweck der Erbschaft zunichte machen. Ich weiß, dass ich die Instanzvariable direkt ändern kann (_speed = 10;), möchte es aber nicht. Ich bin mir sicher, dass etwas mit meinem Verständnis nicht stimmt. Vielen Dank!

// Example 
@interface Ship : Vehicle 
@end 

@implementation 
- (void) someOtherMethod { 
    [self setSpeed: 2]; // DOES NOT WORK, would like it to 
} 
@end 
+0

denke ich, was ich frage ist, wie erbe ich, dass privat @interface somename() Kategorie .. – Patrick

+1

I‘ Ich rate, Sie können die private Schnittstelle über eine Kopfzeile teilen, die nur für abgeleitete Klassen gedacht ist Ses zu umfassen. (Ich habe das selbst nicht versucht, daher der Kommentar anstelle einer Antwort.) –

Antwort

7

Aber jetzt, wenn ich diese Klasse erben, hat die abgeleitete Klasse nicht mehr die Set-Accessor-Methode (setSpeed ​​in meinem Fall).

Eigentlich hat es die Menge Accessor, es ist nur, dass der Compiler nicht darüber informiert. Sie haben die Wahl:

  • die Klassenerweiterung setzen (die @interface Vehicle() .... @end Bit in einer separaten Header-Datei, die in die .m für Fahrzeuge und die Unterklassen (oder verwenden Sie eine Kategorie)
  • neu deklarieren die Lese-/Schreib-Eigenschaft importiert wird in einer Klasse-Erweiterung für die Unterklasse. eine Warnung zu vermeiden, @dynamic speed in der Umsetzung der Unterklasse verwenden.
+0

Ah, danke, ich erinnere mich vage daran, irgendwann über @dynamic gelesen zu haben. Das klingt richtig, da Sie und Marcelo auf der gleichen Spur sind. Extra ++ Punkte für die verschiedenen Lösungen. Ich werde es versuchen, wenn ich nach Hause zu meinem Mac komme und dieses richtig ankreuze. Irgendeine Möglichkeit, dies mit Protokollen zu tun? Redeklingeln scheint langweilig, aber ich kann damit leben. Danke noch einmal. – Patrick

+0

UPDATE: Getestet oben, funktioniert super. Ich erkannte, dass beide Lösungen tatsächlich gleich sind, die zusätzliche Headerdatei spart nur das Kopieren/Einfügen des Blocks. Beachten Sie auch, dass es keine Warnung ausgibt, wenn ich synthesize anstelle von dynamic verwende, oder dass sich die Funktionalität ändert. – Patrick

+0

@Patrick: Wenn Sie '@ synthesize' verwenden, werden neue Accessoren und wahrscheinlich ein neues ivar für die Unterklasse generiert, verwenden Sie also' @ dynamic'. – JeremyP

4

Da es nicht so etwas wie ‚geschützte‘ Methoden ist, benötigen Sie einen privaten gemeinsamen Header, wo Ihre anonyme Kategorie geht zu erstellen. Dann enthalten sowohl Ihre ursprüngliche Implementierung als auch Ihre abgeleiteten Klassen diese Kopfzeile, um Zugriff auf diese "privaten" Daten zu erhalten.

+0

Gut gesagt, ich nehme an, dass es in diesem Ansatz keine Namenskonvention für die Header-Datei gibt. Ich verwende BaseClassNamePrivate, aber das ist trivial. – Patrick

Verwandte Themen