2015-04-30 8 views
7

Questo è qualcosa di molto affascinante che ho osservato oggi. Forse è così che funziona Objective-C ma non lo sapevo. Vedere il seguente codice:Problema con sottoclasse e superclasse con le stesse proprietà nominate

// ATableViewController.h 
@interface ATableViewController : UITableViewController 
@end 

// ATableViewController.m 
@interface ATableViewController() 
@property (nonatomic) int volly; 
@end 

@implementation ATableViewController 
- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    self.volly = 5; 
} 
@end 

// BTableViewController.h 
@interface BTableViewController : ATableViewController 
@end 

// BTableViewController.m 
@interface BTableViewController() 
@property (nonatomic) int volly; 
@end 

@implementation BTableViewController 
- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    NSLog(@"%d", self.volly); // returns 5 
} 
@end 

Non sono sicuro del motivo per cui quanto sopra è valido. Capisco che ho passato un messaggio 'volutamente' all'oggetto 'sé' che a sua volta probabilmente ha considerato il valore della super classe, ma non dovrebbe essere inizializzato? Qualche spiegazione sarebbe di grande aiuto. Grazie.

MODIFICA: Questo è un grosso problema IMO però. Considerando che non conosco nessuna delle proprietà private definite nella super classe, il mio insieme di valori potrebbe finire per essere diverso.

Ad esempio, uno sviluppatore può impostare un flag booleano hasAppeared in viewDidAppear:. Questo stesso valore verrà impostato per la mia istanza di sottoclasse in viewDidAppear: dopo la chiamata [super viewDidAppear:]. Questo avverrà prima che io possa realizzarlo da solo.

Attualmente, la soluzione è che conosco esattamente la variabile utilizzata dalla super classe e posso evitare di utilizzare lo stesso valore ma ritengo che questo sia un problema più ampio di quanto sembri.

MODIFICA 2: il comportamento è coerente con i file binari (con solo le intestazioni) e con i framework in cui è disponibile l'implementazione.

+0

Anche io sono interessato a questa risposta, si prega di avvisare con un commento se qualcuno dice qualcosa di interessante :) –

+0

Qual è la tua domanda? – Rog

+0

"Perché quanto sopra è valido?" + 'Come non ottenere questo comportamento?' + 'Come evitare questo dato uno sviluppatore potrebbe non conoscere le proprietà private di una superclasse?' – p0lAris

risposta

2

Sto rispondendo a questo senza leggere tutti i commenti.

Non c'è nessun problema qui. Entrambi AViewController (AVC) e BViewController (BVC) hanno ciascuno la propria proprietà privata denominata volly.

Hai creato un'istanza di BVC. Non può vedere la proprietà volly dalla sua classe genitore (perché è privata), solo la sua.

Ora inizia il divertimento.

Viene chiamato il metodo viewDidLoad da BVC. A sua volta chiama [super viewDidLoad];, che ovviamente chiama il viewDidLoad dalla classe AVC. Questo metodo, a sua volta, chiama self.volly = 5;.

La confusione sembra essere con questa linea. Ricordate, self.volly = 5; è davvero una chiamata a:

[self setVolly:5]; 

Sia AVC e BVC avere il (sintetizzata) setVolly: metodo. Poiché self è un puntatore a un'istanza di un oggetto BVC, la chiamata a [self setVolly:5]; provoca una chiamata al metodo setVolly: nella classe BVC nonostante sia chiamata da un metodo nella classe AVC.

Ecco il codice con alcune annotazioni:

La classe 'BVC':

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; // calls the method in `AVC` 
    NSLog(@"%d", self.volly); // returns 5 
} 

La classe 'AVC':

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; // calls the UITableViewController method 
    // The following is really [self setVolly:5]; 
    // Since "self" is a "BVC", the private "volly" property of 
    // the "BVC" class is actually set here. 
    // The private "volly" property of the "AVC" class will still be 
    // 0 after this call. 
    self.volly = 5; 
} 

Alla fine, la sottoclasse non è utilizzando la proprietà privata della classe genitore. La premessa originale nel titolo della domanda è errata.

+0

Sono d'accordo e comprendo. Dalla descrizione nell'OP e dai commenti, abbiamo discernuto che questo è il modo in cui Objective-C funziona e questo è come dovrebbe essere. Ma la mia preoccupazione riguarda principalmente le implicazioni di quanto sopra piuttosto che "come viene fatto". – p0lAris

+0

Proverò a riesaminare il titolo di conseguenza. Grazie. – p0lAris

+0

Qual è l'implicazione che ti riguarda qui? – rmaddy

Problemi correlati