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*)keyEl "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:
{
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;
}
- (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?
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];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.
…
return [valor autorelease]
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!
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]
29 juny 2009 14:24
