2010-02-14 14 views
20

tendo a liberare la mia roba in -dealloc, e ora iPhone OS 3.0 ha introdotto questo metodo -viewDidUnload divertente, dove si dice:Cosa devo fare esattamente in viewDidUnload?

// rilasciare qualsiasi mantenuta subviews di vista principale. // per esempio. self.myOutlet = nullo;

Quindi -viewDidUnload sembra essere chiamato quando la vista del controller di visualizzazione è stata avviata dalla memoria. E se ho delle sottoview collegate alla vista principale del controller della vista, devo rilasciare quelle cose solo QUI, ma non anche in -dealloc?

Questo è confuso. Inoltre, cosa succede se -dealloc fa sì che la vista venga scaricata (rilasciata)? Poi di nuovo, chiamerà -viewDidUnload?

Mi rendo conto della differenza, che -viewDidUnload è solo per il caso in cui la vista stessa viene uccisa, ma il controller della vista rimane in memoria. E -dealloc è il caso in cui l'intera faccenda va nel cestino.

Forse qualcuno può chiarire la confusione.

+1

Domanda simile: http://stackoverflow.com/questions/1158788/when-should-i-release-objects-in-voidviewdidunload-rather-than-in-dealloc –

+0

viewDidUnload è obsoleto in iOS 6! – whyoz

risposta

37

L'intento qui è di "bilanciare" la gestione della sottocategoria. Qualsiasi cosa creata in viewDidLoad deve essere rilasciata in viewDidUnload. Questo rende più facile tenere traccia di ciò che dovrebbe essere rilasciato dove. Nella maggior parte dei casi, il tuo metodo dealloc è un'immagine speculare del tuo metodo init e il tuo viewDidUnload sarà un'immagine speculare del tuo metodo viewDidLoad.

Come si è sottolineato, i metodi viewDid ... devono essere utilizzati quando la vista stessa viene caricata e scaricata. Questo consente un modello di utilizzo in cui il controller di vista rimane caricato in memoria, ma la vista stessa può essere caricato e scaricato come richiesto:

init 
viewDidLoad 
viewDidUnload 
viewDidLoad 
viewDidUnload 
... 
dealloc 

Certo, non fa male a rilasciare le cose nel metodo dealloc come bene, purché li imposti a nil quando li rilasci in viewDidUnload.

La seguente citazione dalla sezione gestione della memoria di Apple UIViewController documentation, descrive in modo più dettagliato:

... in iPhone OS 3.0 e versioni successive, il metodo viewDidUnload può essere un luogo più appropriato per la maggior parte delle esigenze .

Quando si verifica un avviso di memoria insufficiente, la classe UIViewController cancella le sue viste se sa che può ricaricarle o ricrearle in seguito. Se ciò accade, chiama anche il metodo viewDidUnload per dare al codice la possibilità di abbandonare la proprietà di qualsiasi oggetto associato alla gerarchia della vista, inclusi gli oggetti caricati con il file pennino, gli oggetti creati nel metodo viewDidLoad e gli oggetti creati pigramente a runtime e aggiunto alla gerarchia della vista. In genere, se il controller della vista contiene punti vendita (proprietà o variabili non formattate contenenti la parola chiave IBOutlet), è necessario utilizzare il metodo viewDidUnload per rinunciare alla proprietà di tali punti vendita o altri dati relativi alla vista non più necessari.

+0

viewDidUnload non è un mirror di viewDidLoad poiché il metodo Unload imposta su zero le prese. –

+1

A quale metodo di scaricamento ti stai riferendo? Ho dato un'occhiata alla documentazione di UIViewController, ma non ho trovato un metodo con quel nome. Quando ho descritto viewDidUnload come (di solito) un'immagine speculare di viewDidLoad, intendevo in termini di gestione della memoria; vale a dire qualsiasi cosa allocata, copiata o conservata in viewDidLoad dovrebbe essere rilasciata in viewDidUnload. Gli IBOutlet vengono solitamente configurati automaticamente quando viene caricato il file del pennino, quindi anche se sono impostati su zero prima della chiamata a viewDidUnload, ciò non dovrebbe influire su nulla dal punto di vista della memoria. –

+0

Per essere chiari; Posso vedere come sarebbe * possibile * incontrare problemi se dovessi allocare un oggetto in viewDidLoad che diventerebbe inaccessibile in viewDidUnload quando tutti gli IBOutlet sono stati impostati su zero. Ciò costituirebbe una forte indicazione del design errato, tuttavia, poiché un oggetto dovrebbe sempre mantenere un puntatore a qualsiasi memoria che è responsabile del rilascio. –

3

Come si dice viewDidUnload verrà chiamato se self.view = nil, questo in genere si verifica se si riceve un avviso di memoria. In questo metodo è necessario rilasciare qualsiasi sottoview del mainview che può essere facilmente creato con il metodo .xib o loadView.È necessario rilasciare qualsiasi oggetto dati se li si crea in viewDidload o loadView ecc. Poiché questi metodi verranno richiamati per presentare l'utente, tali dati possono essere ricreati facilmente.

0

Quando si riceve un avviso di memoria, di solito il viewcontroller scaricherà la vista ma non sarà dealloc.
Tutto ciò che può essere ricreato facilmente dovrebbe essere scaricato, ma non il modello della vista.

Problemi correlati