Si dovrebbe trattare solo con i tuoi Ivars in init
e dealloc
o dove assolutamente richiesto da un dettaglio di implementazione (come ad esempio all'interno della funzione di accesso per sé, o in cui è effettivamente necessario un indirizzo di memoria). Oltre che in quei luoghi, è necessario utilizzare sempre l'accessor, ovvero [self foo]
anziché _foo
.
self.foo
è solo zucchero sintattico attorno alla chiamata effettiva, ovvero [self foo]
. È importante capire che lo self.foo
è un invio di messaggi ObjC standard e significa esattamente la stessa cosa di [self foo]
. Per convenzione, si dovrebbe usare la sintassi del punto solo quando ci si riferisce alle proprietà.
Pre-ARC, l'uso diretto di ivars è stata la causa n. 1 di arresti anomali nella mia esperienza.La probabilità che si rovini quando si assegna direttamente ad un ivar senza ARC si avvicina rapidamente al 100% sull'ambito del programma.
Dal momento che ARC, continuo a sostenere che dovresti sempre usare gli accessor (con le eccezioni indicate sopra), ma le ragioni sono più sottili. La ragione principale è che un accessor può essere personalizzato, sia nella classe corrente, in una sottoclasse, sia tramite KVO (che accade al di fuori del tuo codice interamente). Se accedi direttamente a Ivar, allora ignorerai questo. Ad esempio, diciamo che la proprietà è pigramente creata (che è piuttosto comune). Quindi se usi ivar prima che venga creato, otterrai dei bug sottili. Quindi devi ricordare, per quella proprietà, di usare sempre l'accessor. Allo stesso modo, è possibile chiamare setNeedsDisplay
o pubblicare una notifica o simili.
Se si dispone di una regola semplice che dice "userò sempre gli accessor", è facile guardare il codice e sapere che è giusto. Nei pochi casi in cui è necessario aggirare l'accessor, lo _
dice "ciao, fai attenzione qui, sto facendo qualcosa di strano".
Se si dispone di una regola "Utilizzerò le utilità di accesso per le proprietà che ne hanno bisogno, ma non per quelle che non lo richiedono", è quasi impossibile consultare il codice e sapere se è corretto. Lo sviluppatore precedente ha usato l'ivar perché era necessario o solo perché ne aveva voglia? Puoi cambiarlo o no? È molto difficile sapere.
Quindi, anche dopo l'ARC, l'uso costante degli accessor è una buona programmazione difensiva e lo consiglio vivamente.
Beh, questo è super conflitto con la risposta di Ragnar! Cosa ne pensi del mantenimento extra aggiunto passando per il setter? E anche il fatto che altre persone potrebbero lavorare con il codice e cambiare i setter/getter portando a risultati inaspettati? – jgvb
Il mantenimento "extra" non è "extra". È necessario conservare ciò che si deve applicare e l'accessor è il posto giusto per farlo (ciò vale solo per la pre-ARC, ma non riuscendo ad applicarlo correttamente è la causa principale dei crash che ho menzionato). Vuoi usare esattamente gli accessors * perché * altre persone potrebbero lavorare sul codice, e non c'è modo di garantire che tutti sappiano e seguano sempre "quando cambi questo ivar, devi anche ..." Il modo corretto per documentare che il requisito personalizzato è attraverso l'accessor. –
Occasionalmente questo porterà a risultati sorprendenti (ricalcolare qualcosa troppo spesso, per esempio), ma quegli effetti collaterali sono quasi sempre nella mia esperienza molto più facile da debugare del fatto che non sapevi che dovevi chiamare 'setNeedsDisplay' dopo aver impostato l'ivar. Ciò porta a cose che "tipo di lavoro, tranne quando non lo fanno", che sono estremamente difficili da eseguire il debug. L'esecuzione di una funzione di accesso quando non sapevi che si sarebbe verificato si presentava nella traccia dello stack. Non riuscendo a eseguire una funzione di accesso che non sapevi di dover eseguire ... è difficile da trovare. –