2013-06-19 11 views

risposta

8

È 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 
+0

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

+0

@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. –

+0

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

3

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.

+0

Già. È un po 'vecchio e non molto ufficiale, ma un buon modo di pensare. – uchuugaka

Problemi correlati