2009-02-24 13 views
12

Sono nella parte del mio processo di sviluppo per rintracciare arresti anomali e perdite di memoria. Come strategia, metti messaggi NSLog o notifiche di alcuni di questi in didReceiveMemoryWarning:? La documentazione per questo metodo è piuttosto scarsa. È esatto dire che prima che si verifichi un crash, l'UIViewController attiverà quel metodo? È un punto di partenza prima di andare avanti con gli strumenti?iOS: disponibilità di didReceiveMemoryWarning:

risposta

28

OK, parecchie cose da notare:

  • didReceiveMemoryWarning sarà chiamato prima di un incidente out-of-memoria. Non altri arresti anomali. Se si gestisce correttamente l'avviso e si libera la memoria, è possibile evitare le condizioni di esaurimento della memoria e non l'arresto anomalo.
  • È possibile attivare manualmente un avviso di memoria nel simulatore nel menu Hardware. Consiglio vivamente di farlo per testare la tua gestione di didReceiveMemoryWarning.
  • Gli strumenti consentono di eseguire il debug delle perdite (anche se non tutte), non è molto utile per gli arresti anomali.
  • No, non uso personalmente NSLog: ho appena interrotto gli avvisi di memoria quando eseguo il debug.
+0

Hi Airsource, posso chiedere a cosa serve il 'Simulatore -> Hardware -> Simula memoria avviso'? Ogni volta che clicco, viene visualizzato solo il messaggio "Ricevuto avviso memoria simulata". nella console. Come lo uso per "scovare i problemi"? Grazie. – lionfly

+0

@lionfly: è necessario, in risposta a un avviso di memoria, liberare più memoria possibile. La simulazione di un avviso di memoria ti consente di controllare (e eseguire il debug) il percorso del codice. –

3

Lo scopo di didReceiveMemoryWarning è di darvi la possibilità di liberare memoria o pop view per evitare un arresto anomalo. Non lo riceverai in nessun punto prevedibile perché dipende da ciò che l'utente sta facendo. Ad esempio, se l'utente sta ascoltando l'iPod, c'è meno memoria disponibile e lo riceverai prima.

La regola generale è che si dispone di circa 8 MB di RAM con cui lavorare. Quando ti avvicini a questo, puoi aspettarti che l'evento venga sollevato. Se stai assorbendo così tanta RAM deliberatamente, dovresti avere un piano per fare qualcosa al riguardo.

4

UPDATE Come di iOS 6, UIViewController vista non sono più scaricati in risposta ad avvisi di memoria. Invece fai del tuo meglio per rilasciare le risorse che puoi ragionevolmente ricreare (ad esempio i dati memorizzati nella cache) quando viene chiamato il numero didReceiveMemoryWarning.

UPDATE
ho scritto la mia risposta originale quando ero un giovane arrabbiato; i tempi sono cambiati e, fondamentalmente, è sbagliato.

Se si dispone di un'app con un controller a vista singola e si riceve un avviso di memoria, non c'è molto che si possa fare. Ma le cose cambiano drasticamente se si dispone di più controller di visualizzazione, perché è possibile scaricare tutto lo lo stato associato ai controller non frontmost. Infatti, [UIViewController didReceiveMemoryWarning] ti spingerà nella giusta direzione scaricando le tue visualizzazioni non visibili per te (sorpresa!). Quando il controller della vista in primo piano viene rimosso, la vista sottostante viene ricaricata e al massimo l'utente deve essere a conoscenza di un ritardo anche se internamente l'app potrebbe aver eseguito un riavvio completo.

Questo non è un dettaglio che è possibile modificare facilmente, è necessario tenere a mente l'utilizzo della memoria dall'inizio e progettare l'app multiview in pezzi UIViewController facilmente scaricabili. In effetti vale la pena mantenere il proprio codice compatibile con il simulatore solo per utilizzare la sua funzione di avviso memoria.

Quando la memoria è abbondante, nulla viene scaricato e tutto è liscio come la seta, e quando la memoria è bassa le cose continuano a funzionare, anche se più lentamente. Ora direi che questa soluzione al problema della memoria finita è l'ideale.

Per sfruttare questo salone di memoria trucco, sovraccarico esistono ancora i metodi UIViewController viewDidLoad, viewDidUnload, e viewWillUnload (iOS5, utile se lo stato lo scarico richiede la vostra vista, ad esempio, se non si vuole perdere il vostro OpenGL textures & buffer di rendering, su iOS4 è possibile simulare questo sovraccarico didReceiveMemoryWarning e monitorare la visibilità della vista).

ORIGINALE, risposta più Bilious

didReceiveMemoryWarning è assolutamente inutile.

Non c'è alcuna garanzia che se si libera memoria (anche tutto) che non si verrà uccisi.

Nella mia esperienza amara di solito funziona così su 2.x/3.0:

  1. mediaserverd perde un po 'di memoria

  2. mia app viene ucciso

Purtroppo , il mietitore non pensa mai di uccidere mediaserverd.

Quindi, se l'utilizzo della memoria non è colpa tua, hai davvero avuto solo due scelte:

  1. chiedere all'utente di riavviare il sistema (utente si assume è colpa tua, scrive una recensione feroce)

  2. speranza si blocca il colpevole (mediaserverd spesso obbliga!)

+0

Il tempo inizia. viewDidUnload è ora deprecato con queste note, "Le viste non vengono più eliminate in condizioni di memoria insufficiente e quindi questo metodo non viene mai chiamato." e "In iOS 6 e versioni successive, non è necessario cancellare i riferimenti a viste e altri oggetti nel controller della vista."- [fonte] (https://developer.apple.com/reference/uikit/uiviewcontroller/1621383-viewdidunload?language=objc) – jk7

+0

Stavo pensando di aggiornare questa risposta proprio l'altro giorno! –

5

Se l'utente lasciato alcuni applicazioni aperte si avrà poca memoria a portata di dispos al. Quindi talvolta il numero didReceiveMemoryWarning può essere chiamato dal sistema solo dopo 1 MB di utilizzo.

Il sistema chiama questo metodo su tutti i controller di visualizzazione, se si posiziona un NSLog in ciascuno dei controller della vista, lo si noterà.

Quindi il metodo viewDidUnload verrà chiamato dal sistema su tutti i controller di visualizzazione (non dealloc). Quindi devi inserire tutte le istruzioni di deallocation qui.

Devi fare molti esperimenti perché se la tua app è complessa dovrai affrontare molti crash prima di gestirla bene.

Problemi correlati