Confusione continua su ivar e proprietà nell'obiettivo C

1

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.

    
posta Earl Grey 03.06.2012 - 16:51
fonte

2 risposte

1

In primo luogo, penso che tu stia facendo molte domande, non una.

E la metà delle risposte a queste domande è sempre corretta " Dipende ".

In generale, esporre direttamente gli oggetti ivar è scoraggiato se si mira ad un accoppiamento più sciolto (ovviamente). Anche se penso che quando si tratta di IBOutlet è una pratica accettabile, poiché dopo tutto l'Interface Builder ha il compito di creare l'oggetto.

D'altra parte, una proprietà di readwrite per NSInteger ha poco senso, a meno che tu non stia facendo qualcosa di molto funky, e puoi usare facilmente un ivar.

C'era una volta, in età pre-ARC, c'erano alcune persone che sostenevano sempre usando le proprietà per gli oggetti, dal momento che non devi preoccuparti di retain / release . Tuttavia ora che ARC è ampiamente utilizzato, questo non fa quasi nessuna differenza ed è soprattutto una cosa cosmetica.

Un ultimo consiglio: mirare alla coerenza del progetto.

EDIT: Non sono il più grande fan immaginabile di Design Patterns, ma sembra che la maggior parte delle tue domande trovi la migliore risposta in questo libro.

    
risposta data 03.06.2012 - 17:43
fonte
0

Bene, come già detto, ci sono così tante domande:)

Prima di tutto, dovresti leggere di più sulle proprietà e gli interi principi dell'obiettivo-C. Nel moderno stile Objective-C non dovresti usare affatto gli ivar. Solo proprietà con alcune eccezioni molto rare. Per le proprietà private c'è qualche trucco insolito: le estensioni di classe. Dovresti assolutamente leggere su categorie ed estensioni poiché sono meccaniche molto potenti e utili. Mantieni le tue proprietà private e tutti i punti vendita nell'estensione di classe e nessuno la vedrà fuori dall'implementazione di classe. Ma sarai ancora in grado di accedere ai tuoi punti vendita in Interface Builder! È una soluzione straordinaria che uso tutti i giorni e mi fa sentire bene.

Ora per la tua domanda su ParserManager . Come detto sopra, dipende. Se non vuoi che l'effettivo NSXMLParser sia accessibile direttamente al di fuori del gestore (è meglio non farlo :)), lasciatelo semplicemente dentro e crea nel gestore. Consiglierei di crearlo nel metodo init a causa dell'inizializzazione molto pesante e continua di un oggetto così grande. Sì, hai sprecato un po 'di memoria per questo molto prima che tu ne abbia effettivamente bisogno, ma avrai un accesso molto più rapido quando sarà il momento.

    
risposta data 07.08.2013 - 05:27
fonte

Leggi altre domande sui tag