2009-03-22 11 views
6

Al agregar elementos a NSMutableDictionary utilizando el método setValue:forKey: (supongo que esto se generaliza a cualquier NSObject) ¿retiene el diccionario el segundo parámetro, el NSString?¿[NSMutableDictionary setValue: value forKey: key] retiene la clave NSString?

Por ejemplo:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; 
NSString *theString = @"hello"; 
int i; 
for (i=0; i<[theString length]; i++){ 
    NSNumber *myInt = [NSNumber numberWithInt:i]; 
    NSString *character = [NSString stringWithFormat:@"%C",[theString characterAtIndex:i]]; 
    [dict setValue: myInt forKey:character]; 
} 
[dict release]; 
[pool release]; 

Claramente, no hay razón para liberar myInt en el bucle, es retenido por dict por lo que no puede ser liberado hasta que el final del código. ¿Pero es lo mismo cierto para character? Mi pensamiento es que si NSMutableDictionary almacena la cadena de alguna otra forma, entonces se podría crear un grupo temporal alrededor del ciclo y liberar esas cadenas en lugar de esperar hasta el lanzamiento del diccionario.

También estoy curioso en cuanto a por qué retainCount de character es 7fffffff como si se trata de una NSConstantString, esperaría stringWithFormat para devolver un objeto NSString que habría que retener, pero eso no parece ser el caso.

+0

Simplemente un punto fino que no merece una respuesta: en el código para 10.4 y posterior, generalmente es preferible utilizar [sumidero de piscina] en su lugar: cuando el GC está encendido, el drenaje proporciona una pista de que * podría * ser un buen es hora de recopilar referencias antiguas, mientras que la publicación se convierte en no operativa. Con GC desactivado, funcionan de manera idéntica. –

+0

Esta es una vieja pregunta, pero probablemente quieras usar 'setObject: forKey:' en su lugar. [ver aquí] (http://stackoverflow.com/questions/1249634/wheres-the-difference-between-setobjectforkey-and-setvalueforkey-in-nsmutabl) –

Respuesta

8

Es muy común en Cocoa para los parámetros NSString que se copiarán en lugar de retener. Esto se debe a que podría haber facilitado al diccionario una instancia de NSMutableString. Como el valor de la cadena podría cambiar, NSDictionary realiza una copia.

Pero, independientemente de cómo realmente funciona NSMutableDictionary, no tiene que preocuparse si se debe conservar character. Una vez que lo haya pasado al NSMutableDictionary como parámetro, en realidad es el problema de esa clase decidir cómo almacenar los datos, a menos que la documentación especifique que el mantenimiento de los objetos es su responsabilidad.

Tampoco me preocuparía demasiado acerca del retainCount de ningún objeto. Seguir el conteo retenido de un objeto muy de cerca puede llevarte a agujeros de conejo que te hacen girar las ruedas.

Finalmente, realmente no creo que deba crear su propio grupo de autorrelease aquí. A menos que sepa con absoluta certeza que theString va a ser muy largo, o que ya ha observado una gran utilización de memoria en Instruments, agregar el grupo de autorrelease es una optimización innecesaria.

4

No es necesario que retenga character allí, el diccionario lo conserva cuando lo establece como clave y su propio código no necesita retenerlo.

Además, no necesita preocuparse acerca de por qué el recuento de retenciones no es el esperado. Tal vez el framework de Foundation tiene instancias tipo Flyweight de una carga de instancias de un solo carácter NSString. En cualquier caso, si tiene la administración de memoria correcta siguiendo las pautas, estará bien independientemente de lo que haga el framework detrás de escena. http://iamleeg.blogspot.com/2008/12/cocoa-memory-management.html

Cuestiones relacionadas