Gestio de memoria

Hola he vist el screancast de gestio de memoria y estic probant coses pero tinc un dubte:

Tinc aixo:

+(NSString*)RecogeDatosPlist:(NSString*)path:(NSString*)key
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString *valor = [[[NSString alloc]init]autorelease];
NSDictionary *dict;

if ([self comprueba_si_existe:path] == TRUE) {
dict = [NSDictionary dictionaryWithContentsOfFile:path];
valor = [dict valueForKey:key];

NSLog(@"dict = %d", [dict retainCount]);
NSLog(@"valor = %d", [valor retainCount]);
}

[pool drain];
[pool release];

NSLog(@"valor = %d", [valor retainCount]);
return valor;
}
El "dict" es alliberat be, pero el valor no, de totes formes no esta be alliberarlo per que es retornat al final, per lo que he entes el que recull el valor es el que te que alliberarlo i tinc aixo:

- (IBAction)recogedatosplist:(id)sender
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
NSString *valor2 = [ficheros RecogeDatosPlist:@"/Users/kuru/Desktop/luis.plist" :@"numero"];
NSLog(@"valor nombre4 = %@",valor2);

[pool drain];
[pool release];

Pero em sembla que tampoc es allibetat aixi tinc que fer algo mes, i ¿com puc comprobar si es alliberat?

Lluis  sep  29 juny 2009 13:57

Viam,

0.- Si treballes amb recolector de brossa (garbage collector) que per defecte està activat. Els "retain", els "release" i els "autorelease" no fan cap efecte.

1.- La norma diu que qui crea l'objecte, el reté o en fa una còpia és l'encarregat d'alliberar-lo. Ja sigui amb un release o amb un autorelease.

2.- Hi ha una NSAutoreleasePool al bucle principal del programa que s'allibera cada cop que hi passa. És a dir que no cal crear una altra NSAutoreleasePool excepte que tinguis molta informació per eliminar i no pots esperar a un cicle normal del programa. Jo els utilitzo en mètodes que utilitzen moltes variables i que duren bastanta estona.

3.- Si un valor l'has de retornar, no el pots alliberar abans de retornar-lo. Així en el teu cas, no hauries de fer un "autorelease" fins quan el retornes. Si no t'és possible pots fer un "retain" de més abans de fer el "drain" o el "release". Així serà l'altra NSAutoreleasePool qui s'encarregui d'alliberar-la:

NSString *valor = [[NSString alloc]init];

return [valor autorelease]
Tot i que pot ser que et funcioni, si l'has afegit dins d'un altre objecte que l'ha retingut. Però no te'n pot fiar d'això. És una mala pràctica.

4.- Per comprovar si està alliberat, cal comprovar el retainCount. Però pensa que si has fet un "autorelease" no s'allibera fins que la pool ho fa.

Salut!

Xin  sep  29 juny 2009 14:20

M'he deixat un punt.

5.- Pensa que els mètodes de classe ja retornen la variable alliberada (autorelease). Així que si el "valor" l'assignes amb un d'aquests mètodes hauries de fer-hi un "retain". Així:

NSString *valor = [[NSString stringWithString:@"el valor"] retain];

return [valor autorelease]

Xin  sep  29 juny 2009 14:24

Selecciona'l abans d'enviar el commentari