2016-03-09 18 views
8

La mia conoscenza di ARC è stata testata oggi, sono inciampata su this article e ha un esempio sotto l'intestazione "Annidamento di dichiarazioni" che nella mia mente sembra sbagliato.ARC conserva gli oggetti allocati all'interno di un parametro del metodo

example

Nell'esempio che mostrano incorporati sopra, la linea evidenziata con una sottolineatura verde dice che la stringa alloced all'interno della funzione dovrebbe prima ottenere un conteggio conservare +1 quando essendo creato, poi di nuovo quando si aggiungono +1 all'array, quindi una volta che l'array è stato annullato dopo il ciclo for, il conteggio di mantenimento della stringa si ridurrebbe di 1, lasciando la stringa originale con un conteggio di ritenzione pari a 1, quindi non deallocata.

avrei assunto il compilatore sarebbe stato abbastanza intelligente per fare almeno un oggetto del genere in realtà non hanno un conteggio di trattenere inizialmente, dal momento che se hai appena avuto

[[NSString alloc] initWithFormat:@"Name 1"]]; 

questa stringa viene alloced avrebbe nulla puntando ad esso e verrebbe rilasciato quando il pool di autorelease giunge al termine invece di avere un conteggio dei ritardi pari a 1 per sempre. quindi perché avrebbe un comportamento diverso quando è in un parametro di una funzione? (a meno che quella riga abbia un conteggio di ritenzione pari a 1 e questa è in qualche modo una perdita di memoria? altrimenti potrebbe avere un conteggio di ritenzione di 1 fino alla fine del suo ambito al massimo sicuramente, ma allora quella logica si applicherebbe se anche un suo parametro presumibilmente)

Questo articolo è errato o la mia comprensione dell'ARC è difettosa?

+0

L'articolo è errato. E perché continuano a mostrare 'alloc init', mentre abbiamo metodi di convenienza da usare negli ambiti dei metodi ... Strano. –

+2

L'articolo è sbagliato (come indicato di seguito). Troverai i dettagli cruenti in http://clang.llvm.org/docs/AutomaticReferenceCounting.html#retained-return-values: * "Quando ricevi un risultato di ritorno da tale funzione o metodo, ARC rilascia il valore al la fine dell'espressione completa è contenuta all'interno, fatte salve le solite ottimizzazioni per i valori locali. "* - Non sono richiesti sia' name = nil' che 'array = nil' per" help ARC release memory ". –

risposta

5

L'articolo è errato.

La tua comprensione è sostanzialmente corretta, anche se il pool di autorelease non è utilizzato in questo caso. Il sub-espressione:

[[NSString alloc] initWithFormat:@"Name 1"]]; 

restituisce un oggetto di proprietà, come fanno tutti i init metodi. Tale oggetto viene passato a addObject: e anche l'array diventa proprietario. Dopo che ARC ha rilevato che la stringa non è più richiesta dal metodo e ne ha abbandonato la proprietà, lasciando l'array come unico proprietario.

HTH

+0

ah, quindi, se non fosse un parametro, si limiterebbe a rinunciare la sua proprietà immediatamente dopo essere stata dichiarata, ma a quel punto è deallocata, o arriva alla fine del pool di autorelease prima di essere deallocata?(sto assumendo il primo da quando hai menzionato che il pool di autorelease non è usato, ma sembra un po 'ambiguo di quale caso stai parlando, voglio solo chiarire) – Fonix

+0

Il pool di rilascio automatico non è usato in questo caso perché non è un auto rilasciato oggetto. – rmaddy

+0

capito, grazie! – Fonix

4

ARC non è imperfetto qui. Sembra che l'articolo sia sbagliato.

ARC rilascerà l'oggetto parametro assegnato come previsto mentre l'array mantiene il suo riferimento. Una volta rilasciato l'array, l'oggetto non avrà più riferimenti e sarà anche deallocato, come previsto.

+0

se siamo in grado di ottenere un po 'più di persone di essere d'accordo con noi, forse magari postare questo nella sezione commenti degli articoli per avvisare loro o chiunque altro che trova l'articolo – Fonix