Dopo quasi 8 mesi di programmazione iOS, sono di nuovo confuso circa l'approccio giusto. Forse non è la lingua ma un principio OOP di cui sono confuso. Non lo so ..
Stavo provando C # qualche anno fa. C'erano campi (variabili private, dati privati in un oggetto), getter e setter (metodi che esponevano qualcosa al mondo) e proprietà che erano la cosa esposta. Ad esempio, mi è piaciuta l'eleganza della soluzione
potrebbe esserci una classe che avrebbe una proprietà chiamata DailyRevenue
... un float ... ma non c'era alcuna variabile privata chiamata dailyRevenue
, c'era solo un campo - una serie di entrate per singola transazione ... e il getter per DailyRevenue
proprietà ha calcolato le entrate in modo trasparente.
Se in qualche modo gli interni del calcolo delle entrate giornaliere cambiassero, non influenzerebbe in alcun modo qualcuno che ha consumato la mia proprietà DailyRevenue
, poiché sarebbe stato protetto dall'implementazione getter.
Ho capito che a volte c'era, e a volte non c'era una relazione 1-1 tra campi e proprietà. A seconda dei requisiti. Sembrava ok secondo me. E quelle proprietà sono IL modo per accedere ai dati nell'oggetto.
Conosco la differenza tra parole chiave private, protette e pubbliche.
Ora passiamo a Objective-C.
Su quale fattore dovrei basare la mia decisione sul fare qualcosa solo un ivar o renderlo come una proprietà? Il modello mentale è lo stesso che descrivo sopra? So che gli ivars sono "protetti" di default, non "privati" come in C # .. Ma questo è ok penso, non un grosso problema per il mio attuale livello di comprensione dell'intero sviluppo di iOS. Il punto è che gli ivar non sono accessibili dall'esterno (dato che non li rendono pubblici .. ma non lo farò).
La cosa che offusca la mia chiara comprensione è che posso avere IBOutlets
da ivars. Perché vedo i dati degli oggetti interni nell'interfaccia utente? * Perché è ok? * D'altra parte, se faccio un IBOutlet
dalla proprietà, e lo faccio non renderlo di sola lettura, chiunque può cambiarlo. Anche questo va bene?
Diciamo che ho un oggetto ParseManager
. Questo oggetto userebbe una classe di framework Foundation
chiamata NSXMLParser
. Ovviamente il mio ParseManager
utilizzerà le funzionalità di NSXMLParser
ma eseguirà anche un po 'di lavoro aggiuntivo. Ora la mia domanda è, chi dovrebbe inizializzare questo oggetto NSXMLParser
e in che modo dovrei fare riferimento ad esso dall'oggetto ParseManager
, quando è necessario analizzare qualcosa.
A) ParseManager
- 1) nel suo metodo di inizializzazione predefinito (possibile qui ivar - o - ivar + ppty)
- 2) con lazyloading in getter (richiesto un ppty qui)
B) Qualche altro oggetto - chi passerà un riferimento all'oggetto NSXMLParser
all'oggetto ParseManager
.
- 1) in alcuni inizializzatori personalizzati ( initWithParser:(NSXMLPArser *)parser
) durante la creazione dell'oggetto ParseManager
..
A1 - il problema è che creiamo un parser e sprechiamo memoria mentre non è ancora necessario. Tuttavia, possiamo essere sicuri che tutti i metodi che fanno parte di ParserManager
oggetto, possono utilizzare l'ivar in modo sicuro, poiché esiste.
A2: il problema è che NSXMLParser
è esposto al mondo esterno, sebbene potrebbe essere di sola lettura. Vogliamo che un parser sia esposto in qualche scenario?
B1 - questo potrebbe essere utile quando vorremmo usare più tipi di parser .. Non lo so ...
Comprendo che i requisiti e il linguaggio dell'architettura non sono gli stessi. Ma chiaramente i due sono in relazione.
Come uscire da quel pasticcio di mio?
Per favore, sopportami, non sono stato in grado di trovare una sola domanda definitiva. E in secondo luogo, è meglio non spaventarmi con qualche newspeak super-avanzato che parla di alcuni interni pazzi (cosa fa il compilatore) e casi limite.