Quando si sottoclama una classe Apple che elenca ivars privati nel file .h, è corretto redeclare questi ivar nella propria sottoclasse nell'estensione di classe @interface all'interno del file .m della sottoclasse per renderli accessibili all'implementazione della sottoclasse. ?È corretto dichiarare ivars privati in una sottoclasse per renderli accessibili?
risposta
È necessario tenere a mente che dichiarare una variabile di istanza in una sottoclasse non ridichiarare una variabile di istanza superclasse esistente con lo stesso nome, indipendentemente dal ridichiarazione presunto essendo nell'interfaccia pubblico o un'estensione di classe. Anche se usi lo stesso nome, è una variabile di istanza diversa.
Puoi provarlo tu stesso. Ad esempio:
@interface Base : NSObject {
@private
int _number;
}
@end
@implementation Base
- (id)init { self = [super init]; if (self) _number = 10; return self; }
- (void)logNumber { printf("base = %d\n", _number); }
@end
@interface Derived : Base
@end
@interface Derived() {
int _number;
}
@end
@implementation Derived
- (id)init { self = [super init]; if (self) _number = 20; return self; }
- (void)logNumberDerived { printf("derived = %d\n", _number); }
@end
int main(void) {
Derived *o = [Derived new];
[o logNumber];
[o logNumberDerived];
return 0;
}
uscite:
base = 10
derived = 20
perché _number
in superclasse è diverso da _number
in sottoclasse (estensione). Se si controlla i simboli in uscita binaria con nm -a
, si noterà che il compilatore genera due simboli diversi:
s _OBJC_IVAR_$_Base._number
s _OBJC_IVAR_$_Derived._number
ho trovato qui la risposta che corrisponde esattamente la mia: http://lists.apple.com/archives/cocoa-dev/2007/Feb/msg00939.html
Se l'hanno fatta @private e non @protected si dovrebbe supporre che è per una ragione. Che la ragione potrebbe naturalmente essere semplicemente che è prudente rendere tutto @private finché non si sa una buona ragione per non ...
Detto questo, si potrebbe molto definitivamente non essere OK per accedervi direttamente , anche se è tecnicamente possibile.
La cosa sicura da fare è rifare tutto nella propria classe, mentre richiede al manutentore della superclasse di esporre la funzionalità necessaria nell'interfaccia pubblica/protetta.
Già. È un po 'vecchio e non molto ufficiale, ma un buon modo di pensare. – uchuugaka
- 1. Dichiarare ivars nella superclasse o @synthesize nella sottoclasse?
- 2. Modo corretto per caricare un pennino per una sottoclasse UIView
- 3. Qual è il modo corretto per dichiarare una proprietà readonly per iOS utilizzando ARC
- 4. Qual è il modo corretto per dichiarare un Doctype HTML5.
- 5. C'è qualche ragione per dichiarare ivars se stai usando le proprietà esclusivamente in Objective-C?
- 6. Perché una sottoclasse @property con nessun ivar corrispondente nasconde i superclasse ivars?
- 7. È possibile dichiarare una seconda interfaccia @ per una categoria?
- 8. Modo corretto per dichiarare l'oggetto JSON in Typescript
- 9. Modo corretto per dichiarare più vars in PHP
- 10. metodi privati in Ruby
- 11. È brutto dichiarare una classe vuota?
- 12. Qual è il modo sintatticamente corretto per dichiarare una struttura C?
- 13. Come memorizzare i dati utente privati crittografati nel database, ma renderli disponibili ad altri utenti scelti?
- 14. Accesso ai campi privati della superclasse usando la parola chiave super in una sottoclasse
- 15. Qual è il modo migliore per dichiarare una variabile globale in Angular 2/Typescript
- 16. RDF approccio corretto alla sottoclasse di
- 17. Modo corretto per dichiarare/definire oggetto cout-like personalizzato
- 18. Accesso ai membri privati di una superclasse
- 19. Qual è il corretto "modo C++" per fare variabili globali?
- 20. Qual è il modo corretto di creare una sottoclasse di Ocaml con metodi aggiuntivi?
- 21. Evidenziazione una sottoclasse UIControl
- 22. Il sovraccarico di un metodo in una sottoclasse in C++
- 23. Qual è la procedura migliore per denominare metodi privati e statici privati in C#?
- 24. Come convertire i vettori int per renderli mobili in GCC?
- 25. Qual è il modo migliore per dichiarare una variabile globale?
- 26. Protocolli "privati" Objective-C?
- 27. In che modo i membri pubblici e privati devono essere implementati nell'obiettivo-c?
- 28. È corretto dichiarare un metodo asincrono come invalido per disattivare l'avviso CS4014?
- 29. Dichiarare una variabile in RedShift
- 30. Metodi privati in una classe Mootools
Interessante. Ma presumibilmente, se sono altrimenti dichiarati uguali, il tuo esempio indica che quello indicato nei metodi implementati in super sarà quello dichiarato in super. Quello indicato nei metodi dichiarati in sottoclasse sarà quello dichiarato nella sottoclasse? – uchuugaka
@uchuugaka corretto. Dal momento che la superclasse ivar è privata, la sottoclasse non può accedere a quell'arena e vede solo il proprio, diverso ivar. È necessario fare uno sforzo extra (ad esempio, utilizzando l'API runtime Objective-C) per poter accedere alla superclasse ivar. –
verificato. Ho provato questo con diverse varianti, setter, getter e proprietà e sicuro come può essere è come dici tu. E questo comportamento potrebbe facilmente "sembrare" funzionare, quando un ivar è un oggetto la cui classe è una classe genitrice dell' ivar che "penso" sto redecando ... (sì è così che sono arrivato a questa domanda, ma usando un il tipo C ivar invalicabile è più chiaro!) – uchuugaka