Ho un'app MonoTouch con UITabBarController, con ciascuna delle schede è un UINavigationController. Alcuni di questi avvolgono un UIViewController che aggiunge UITableView e una UIToolbar, mentre altri racchiudono un DialogViewController.Gestione memoria/risorse utilizzando MonoTouch e MonoTouch.Dialog
Non ho prestato molta attenzione alla gestione della memoria/visualizzazione fino ad ora (sono stato principalmente in esecuzione nel simulatore), ma come ho iniziato a testare su un dispositivo reale, ho notato alcuni guasti dovuti a condizioni di memoria insufficiente (ad esempio, l'app viene terminata e scopro dal mio registro che DidReceiveMemoryWarning è stato chiamato prima). Altre volte noto pause prolungate nella reattività dell'app che presumo siano dovute a un ciclo GC.
Finora ho assunto che ogni DialogViewController che inserisco nello stack nav pulirà le sue viste e altre cose verranno allocate quando lo popò. Ma sto iniziando a rendermi conto che probabilmente non è così facile, e che ho bisogno di iniziare a chiamare Dispose() sulle cose.
Esistono best practice su come gestire la gestione delle risorse e della memoria con MonoTouch e MT.D? In particolare:
- È necessario chiamare Dispose su un DialogViewController dopo che è spuntato? Se sì, dove è meglio farlo? (ViewDidUnload? DidReceiveMemoryWarning? Destructor?)
- Il DVC dispone automaticamente di oggetti come il RootElement che gli viene passato o devo preoccuparmi di questo? Che ne dici di UIImages che carica come parte del rendering di una cella di una tabella (ad esempio StyledStringElement)?
- Ci sono dei luoghi in cui dovrei chiamare GC.Collect() per ottimizzare le raccolte in modo da non perdere un po 'di reattività quando si verifica un GC?
- Il garbage collector generazionale aiuta con i problemi di interattività ed è abbastanza stabile da poter essere utilizzato in un'app di produzione? (Credo sia ancora pubblicizzato come "sperimentale" in MonoDevelop 3.0.2/MT 4.3.3)
- Cosa devo fare in DidReceiveMemoryWarning per ridurre la probabilità che iOS spari la mia app? Dal momento che ogni controller di visualizzazione non visibile sembra ricevere questa chiamata, suppongo che dovrei pulire le risorse del controller di visualizzazione ... dovrei fare lo stesso tipo di cose che faccio in ViewDidUnload?
- Non riesco a richiamare il mio ViewDidUnload (anche dopo aver ricevuto DidReceiveMemoryWarning). In effetti non ricordo di averlo mai visto nel mio log. Se iOS ha sempre chiamato il mio ViewDidUnload dopo DidReceiveMemoryWarning, ho potuto semplicemente fare tutto il cleanup in ViewDidUnload ... Qual è il modo migliore per dividere la responsabilità di cleanup tra ViewDidUnload e DidReceiveMemoryWarning?
Mi scuso per il carattere generale di questa domanda - questo mi sembra un buon argomento per un whitepaper, ma non ho trovato alcuna ...
Aggiornamento: per rendere la questione più concreta : dopo aver usato Instruments e il profiler Xamarin Heapshot, mi è chiaro che sto perdendo UIViewControllers quando l'utente apre lo stack di navigazione. Rolf ha depositato un bug per questo e ha due dups, quindi questo è un vero problema per più di me. Sfortunatamente non ho trovato una buona soluzione per i controllori di perdite UIViewControllers - Non ho trovato un buon posto per chiamare Dispose() su di essi. Il posto naturale per liberare risorse allocate da ViewDidLoad è nel messaggio ViewDidUnload, ma non viene mai chiamato sul simulatore, quindi il mio footprint di memoria continua a crescere.Sul dispositivo, vedo DidReceiveMemoryWarning, ma sono riluttante a utilizzare questo come spazio per liberare il mio viewcontroller e le sue risorse poiché non sono sicuro che iOS scaricherà effettivamente la mia vista, e quindi non è garantito che il mio ViewDidLoad venga chiamato di nuovo o (portando ad un ViewDidAppear che avrebbe bisogno di codificare in modo difensivo contro le situazioni in cui le sue risorse sottostanti sono state smaltite). Mi piacerebbe avere qualche consiglio su come uscire da questo casino ...
Questo è un sacco di informazioni preziose, grazie per mettere tutto insieme. Solo una nota per i futuri lettori: da iOS 6, il sistema non chiamerà 'ViewDidUnload'. –