2010-07-06 5 views
6

Quando l'applicazione passa allo stato di esecuzione in background, la quantità di memoria utilizzata è buona. Nel video di Apple si dice che la memoria sporca dovrebbe essere ridotta il più possibile.iOS4: commutazione rapida dei contesti

Ma nella mia app, sto usando il controller di navigazione per spingere e far apparire le viste. Dopo essere passati da circa 20 pagine diverse, gli utilizzi della memoria sporca raggiungono i 30 MB circa.

Anche su "dismissModalViewControllerAnimated" e "popViewControllerAnimated", dealloc non viene chiamato.

ho due dubbi:

  1. Con la quantità di memoria sporco è accettabile per andare a vivere?
  2. Qual è l'alternativa del controller di navigazione per supportare il pulsante Indietro?

Grazie in anticipo.

+0

1. Non 30 MB. I dispositivi iOS meno recenti hanno solo RAM da 128 MB, quindi la tua app lo riempirebbe per circa il 23% ... 2. Se hai una perdita di 30 MB, probabilmente non stai pubblicando qualcosa, da qualche parte, non è "UINavigationController'" colpa di s. –

+0

Hi Douwe, Grazie per la risposta. Perché dubito su UINavigationController perché continuo a spingere i controller della vista al suo interno.E quando apro i controlli della vista dal controller di navigazione, il metodo dealloc non viene chiamato dove sono rilasciate le variabili di istanza definite. E la memoria non viene cancellata da tutte queste variabili di istanza. Sto facendo qualcosa di sbagliato? Devo cancellare le variabili di istanza da qualche altra parte e non in dealloc? – Sunil

+0

Hai altri riferimenti ai tuoi controller di visualizzazione, altrove nella tua app? Se li stai inserendo, ma hai ancora un riferimento da qualche altra parte al controller, non otterrà GCed – blueberryfields

risposta

4

È ancora possibile mantenere i vostri UIViewController mantenuti se dealloc non viene chiamato.

Forse stai impostando delegati o altre classi in questi UIViewControllers che hanno mantenuto e referenziato il backup dell'albero (riferimenti circolari).

Un modo per eseguire il debug di questo è sovraccaricare conservare e rilasciare in UIViewController e impostare un punto di interruzione e registrare il retainCount.

Ecco un frammento magico che lascio andare in giro che mi aiuta un sacco quando non riesco a capire perché sto ancora mantenendo qualcosa.

- (id)retain 
{ 
    NSLog(@"retain \t%s \tretainCount: %i", __PRETTY_FUNCTION__ , [self retainCount]); 
    return [super retain]; 
} 
- (void)release 
{ 
    NSLog(@"release \t%s \tretainCount: %i", __PRETTY_FUNCTION__ , [self retainCount]); 
    [super release]; 
} 
- (id)autorelease 
{ 
    NSLog(@"autorelease \t%s \tretainCount: %i", __PRETTY_FUNCTION__ , [self retainCount]); 
    return [super autorelease]; 
} 

__PRETTY_FUNCTION__ è una speciale macro nascosta in clang che dà un Objective-C nome della funzione bella come un array di caratteri.

0
  1. Quando un iOS inizia a esaurire la memoria, tenta di eliminare i processi in background che utilizzano più memoria. Quindi, anche se non esiste un numero assoluto, ridurre al minimo la quantità di memoria che si utilizza è una buona idea. Lasciare a 30 Mb equivale a garantire che l'app venga uccisa
  2. A meno che non si desideri modificare l'interfaccia utente, non è necessario utilizzare altro che un UINavigationController da gestire con il pulsante Indietro. Credo che il problema qui è che se dealloc non viene chiamato su un pop o respingere, si dispone di una perdita di memoria

Quasi tutti i controller di vista sono dati che vengono effettivamente memorizzati nella cache e possono essere rigenerato quando l'applicazione ritorna in primo piano . Pensa ai dati che rilasci quando ricevi un avviso di memoria quando l'app è in esecuzione. (Stai rispondendo agli avvertimenti sulla memoria, giusto?) È quella roba che dovrebbe essere rilasciata quando vai in sottofondo.