2011-08-30 17 views
5

Dopo aver eseguito un test di profilo lungo, ho rilevato che in uno dei miei file ".m" si verifica una perdita di memoria nella sezione viewdidload. ho controllato e il xcode ha evidenziato la parte in cui ho inizializzato le linee di selezione con i valori. il mio programma usa i raccoglitori per l'input dell'utente. e ho 3 5 diversi punti di vista nel mio programma. il primo è un disclaimer, il secondo è un menu in cui l'utente può scegliere il tipo di calcolo che desidera fare. ogni calcolo richiede determinati input che l'utente inserisce da un selezionatore. per es. una vista ha 5 ingressi gestiti da 5 diversi uipicker con array separati per contenere i valori. questi array sono inizializzati con i valori nel metodo viewdidload di quella vista. ecco cosa ho trovato dopo aver eseguito il test:Come posso risolvere una perdita di memoria?

-viewDidLoad .................................. .................................................. ...............

instantiation

Questa è la mia prima volta sviluppando un app e sono un po 'confuso su cosa fare. Qualsiasi aiuto sarebbe apprezzato.

+2

miei occhi male = ( –

risposta

4

Gli oggetti nell'obiettivo c hanno un conteggio. Se questo conteggio di conservazione è maggiore di 0 quando l'oggetto esce dall'ambito di validità (quando si smette di utilizzarlo), perde.

I seguenti cose aumentano il conteggio di conservare

  • [[alloc] init]
  • nuovo
  • copia
  • [conservare]
  • aggiunta di un oggetto a un array
  • aggiunta un oggetto da bambino (ad es. viste)
  • Probabilmente ce ne sono altre, ma non sembrano utilizzare tutti gli altri nel codice

Il seguente diminuzione della trattenere conteggio

  • [liberazione]
  • rimozione di un oggetto da un array
  • se dealloc una matrice, tutta la sua oggetti vengono rilasciati

Si dovrebbe passare attraverso il codice e assicurarsi che ognuno dei ritegni o delle aggiunte a un array corrisponda a una corrispondenza rilascio. (È possibile rilasciare le variabili membro nel metodo dealloc).

EDIT: Jeremy ha fatto un punto valido che la mia risposta non

Una volta che si aggiunge un oggetto a un array, esso assume la proprietà e rilascerà l'oggetto quando è fatto con esso. Tutto quello che devi fare è assicurarti di rilasciare tutto ciò che possiedi secondo le regole di gestione della memoria

Ci sono anche oggetti autorelease, dai un'occhiata a questo esempio;

-(init){ 
    ... 
    stagePickerArray = [[NSMutableArray alloc] init]; 
    for (int i = 0; i < 3; i++) 
    { 
     //this string is autoreleased, you don't have call release on it. 
     //methods with the format [CLASS CLASSwithsomething] tend to be autorelease 
     NSString *s = [NSString stringWithFormat:@"%d", i); 
     [stagePickerArray addObject:s]; 
    } 
    ... 
} 

Credo che l'unica cosa che manca è una chiamata a rilasciare nel metodo dealloc

-(void) dealloc 
{ 
    [stagepickerarray release]; //Do this for each of your arrays 
    [super dealloc]; 
} 
+1

Siamo spiacenti, ma questo è fuorviante. Non è necessario abbinare un'aggiunta a un array con una versione. Una volta aggiunto un oggetto a un array, esso assume la proprietà e rilascerà l'oggetto quando viene eseguito con esso. Tutto quello che devi fare è assicurarti di ** rilasciare qualsiasi cosa possiedi ** in base alle regole di gestione della memoria. – JeremyP

+0

Modificato con una citazione dal tuo commento per chiarire –

+0

Grazie mille :). Sono tornato indietro e ho fatto in modo che tutti gli oggetti che ho conservato fossero correttamente rilasciati, come campi di testo, raccoglitori, barre degli strumenti ecc. Ho anche aggiunto una versione per ciascuno degli array e dopo di che ho eseguito nuovamente il test. Questa volta non ci sono perdite di memoria. Comunque ho una domanda, durante il test ho anche controllato le allocazioni e il totale dei byte era di 9,3mb e il byte live di 1,7 mb è normale? o dovrei essere preoccupato? – cyberbemon

0

In Objective-C è necessario occuparsi del conteggio di conservazione della memoria allocata. Se non ne hai bisogno -> rilasciarlo.

Ogni volta che si Alloc un oggetto, restituisce un oggetto con mantenere count = 1.

Utilizzando mantenere, il conteggio viene incrementato mantenere, utilizzando rilascio, il numero di trattenere ottiene decrementato. Ogni volta che il conteggio dei ritegni è uguale a 0, l'oggetto verrà distrutto.

Così ogni volta che si desidera utilizzare l'oggetto da qualche altra parte è necessario conservarlo. Quindi assicurati che l'oggetto non venga cancellato dopo che l'altra 'persona' (o qualsiasi cosa abbia usato;)) ha chiamato il rilascio.

Questa è stata una descrizione molto molto molto breve. Controllare la seguente guida Memory Management Guide for iOS.

(anche voi volete leggere qualcosa su di ARC - automatica mantengono conteggio - che è nuovo in iOS5 ios5 best practice release retain

+0

Grazie :). Ne darò un'occhiata! . Attualmente sto usando iOS 4 xD – cyberbemon

2

Lo strumento di perdite solo vi dirà dove yo assegnati gli oggetti che si pensa perdite Quindi, è dicendo. voi, per esempio, che

NSString* answer = [NSString stringWithFormat: ... 

alloca un oggetto che non è mai deallocata. Ora, -stringWithFormat: ti dà un oggetto che you do not own e non sembrano per mantenere ovunque. Pertanto, non è necessario per rilasciarlo , quindi non può perdere da solo

Ciò significa che qualcun altro che si è do deve essere mantenuto e non si rilascia mai qualcos'altro. Il primo sospettato sembrerebbe essere stagePickerArray. Verifica che stai pubblicando stagePickerArray da qualche parte. Se è locale a -viewDidLoad, deve essere rilasciato o autorizzato automaticamente prima della fine di tale metodo. Se è una variabile di istanza, deve essere rilasciata nel metodo -dealloc della classe.

+0

Grazie :) Ho dimenticato di aggiungere la versione per l'array! e quella era la causa del problema! – cyberbemon