2010-06-28 12 views
6

Aggiornamento: questa perdita è stata risolta. Se si verificano perdite simili e l'applicazione è multi-thread, è molto probabile che si effettuino chiamate UIKit da un thread in background; fai uso di, ad es. [NSThread performSelectorOnMainThread:] per instradare UIKit chiama al thread principale, che èl'unico posto dove sono consentiti.Le perdite (strumento) segnalano perdite negli oggetti autoreleased

Ho eseguito Leaks sul mio progetto corrente per trovare perdite di recente, e continuo a imbattersi in queste "perdite" che da quello che posso dire non sono realmente fughe di notizie. Il codice seguente, presi direttamente dal progetto, ha due fughe, secondo Perdite:

- (NSArray *)areaForIndex:(int)index 
{ 
    NSMutableArray *a = [NSMutableArray arrayWithArray: 
     [world retrieveNeighborsForIndex:index]]; // leak 1 
    [a insertObject:[references objectAtIndex:index] atIndex:0]; 
    return [NSArray arrayWithArray:a]; // leak 2 
} 

Leak 1 va via se cambio la prima riga: (vedere Update 2-3)

Leak 2 va via se cambio l'ultima riga a:

return a; 

non posso, purtroppo, farlo con perdita 1 perché sto gettando una matrice immutabile, in un uno mutevole. Comunque, arrayWithArray dovrebbe automaticamente autorizzarsi, quindi da quello che posso dire, non dovrebbe perdere nulla. Qualche idea per cui questo sta accadendo?

Aggiornamento: l'ho provato sia sul dispositivo che sul simulatore. La perdita è lì su entrambi. Tuttavia, il simulatore ho un po 'ulteriori informazioni su questa perdita:

La storia della fuga di notizie è la seguente:

# | Category | Event Type | Timestamp | RefCt | Address | Size | Responsible Library | Responsible Caller 
--+----------+-------------+ 
0 | CFArray | Malloc  | 00:09.598 |  1 | 0x474f6d0 | 48 | asynchro   | -[muddyGrid areaForIndex:] 
1 | CFArray | Autorelease | 00:09.598 |  | 0x474f6d0 | 0 | Foundation   | NSRecordAllocationEvent 
2 | CFArray | CFRetain | 00:09.598 |  2 | 0x474f7d0 | 0 | Foundation   | -[NSCFArray retain] 
3 | CFArray | CFRelease | 00:09.611 |  1 | 0x474f7d0 | 0 | Foundation   | NSPopAutoreleasePool 

Le cose che posso discernere da quanto precede è che la matrice autoreleased è in qualche modo conservavo due volte e poi autoreleased, lasciando mantenere conteggio a 1. Non ho idea di dove o perché se ...

Update 2 & 3: ho provato a cambiare la linea per Leak 1 a:

NSMutableArray *a = [[[NSMutableArray alloc] initWithArray: 
     [world retrieveNeighborsForIndex:index]] autorelease]; 

Ho pensato che questo rimosso la perdita, ma non ha, in definitiva. Quindi sono ancora in perdita.

+0

Stai provando sul dispositivo o sul simulatore? – rickharrison

+0

Attualmente solo sul dispositivo. Ma hai ragione, testerò e vedrò come si presenta al Simulatore e si aggiorna. – Kalle

+0

Aggiornato la descrizione sopra per includere ciò che ho capito provandolo sul simulatore. Grazie per il puntatore! :) – Kalle

risposta

2

Anticlimaticamente, questo risolve se stesso come ho risolto un sacco di altri problemi con il mio codice.

Principalmente, il codice aveva un numero di punti in cui gli aggiornamenti dell'interfaccia utente venivano creati al di fuori del thread principale, che è un grande no-no. Uno di questi altri problemi non collegati deve aver innescato la perdita di memoria nel codice precedente, dal momento che non riporta più alcuna perdita (ho 0 perdite così com'è), anche se non ho modificato il codice.

0

Cosa restituisce retrieveNeighborsForIndex?

Esiste la possibilità che il risultato di questo metodo venga mantenuto (non autorizzato)?

+0

Si sta restituendo [neighborOggetti], dove neighbor è un NSMutableSet che contiene un numero di oggetti (9-12). – Kalle

-1

arrayWithArray conserva gli oggetti memorizzati nell'array mutabile. http://www.iphonedevsdk.com/forum/iphone-sdk-development/14285-nsmutablearray-arraywitharray-does-add-retain.html

Si consiglia di rilasciarlo, o più sicuro, ma creare gli oggetti con l'attributo di autorelease impostato. Quando si chiama retrive vicini per indice di rendere tali oggetti autorelease e saranno rilasciati quando la matrice è nsmutable dealloc'ed

EDIT: Una punta mi permetto di aggiungere, quando individuare gli errori di memoria è quello di consentire zombie, e controllare il conteggio dei riferimenti dei tuoi oggetti. È quindi possibile determinare quali non vengono rilasciati e dovrebbe facilitare il tracciamento. Questo link ti mostrerà come configurare il tuo progetto xcode per abilitare gli zombi: cocoadev.com/index.pl?NSZombieEnabled

+0

Lo fa, ma l'array restituito da 'arrayWithArray:' è a sua volta autoreleased, quindi rilasciandolo da solo probabilmente causerà un crash. Detto questo, è probabilmente sicuro restituire l'array mutabile stesso, poiché lo stai creando e restituendolo nello stesso metodo, senza effetti collaterali nascosti. – Wevah

+0

Che funziona per leak 2 (ed è quello che sto facendo ora), ma non risolve la perdita 1, dove sto prendendo un array immutabile in un array mutabile usando arrayWithArray, dal momento che ho bisogno di aggiungerlo prima di tornare esso. – Kalle

+0

La mia risposta è stata per Wevah, a proposito; Shadow ha ragione nel fatto che 'arrayWithArray:' conserva gli oggetti nell'array, ma esso stesso non è contenuto e non dovrebbe essere rilasciato né autorizzato automaticamente. – Kalle

Problemi correlati