¿Cómo lanzar una Variable de Instancia NSMutableDictionary correctamente, con diccionarios anidados, en Objective-C?

StackOverflow https://stackoverflow.com/questions/1402778

Pregunta

Tengo una clase Objective-C que se parece a:

@interface myClass : NSObject
{
    NSMutableDictionary *aDict;
}

Su método de establecimiento se ve así:

- (void) setADict: (NSMutableDictionary *) newDict
{
    [aDict release];
    [newDict retain];
    aDict = newDict;
}

He creado una instancia del objeto, puse datos en aDict y ahora quiero deshacerme del objeto, limpiando su memoria en el proceso. Dos preguntas:

1) ¿Debo liberar aDict en el método myClass de dealloc , como se muestra?

[aDict release];

=============================================== ==============================

2) He anidado varios diccionarios de niños en aDict , representados por keyA y keyB , así:

// aDict:
{
    keyA =     {
        keyA1 = "Hello world";
        keyA2 = 1234;
    };
    keyB =     {
        keyB1 = Earth;
        keyB2 = 25000;
    };
}

¿Se propagará un mensaje [aDict release] " hacia abajo de la cadena " ¿y limpia todos los diccionarios de niños dentro de aDict, incluidos los objetos clave / valor sus ? ¿O tengo que hacer algo más para deshacerme de ellos?

¿Fue útil?

Solución

Sí.

Los objetos de la colección retienen las cosas que están recolectando, por lo que cuando la colección se desasigna, equilibra la retención con un lanzamiento.

Luego, si uno de los diccionarios a los que se aferra está desasignado, también liberará sus pares clave / valor, ya que el diccionario es una colección y los objetos de la colección retienen las cosas que están recolectando.

Lo mismo se aplica a las matrices y conjuntos.

Sin embargo, tiene un error en su código. Tienes:

- (void) setADict: (NSMutableDictionary *) newDict
{
    [aDict release];
    [newDict retain];
    aDict = newDict;
}

Considere el caso cuando newDict es el mismo objeto que aDict . Luego sueltas el diccionario, se desasigna, y luego intentas retenerlo, ¡pero vaya! Ya no está allí.

Hay tres alternativas para arreglar esto. Aquí están:

    - (void) setADict: (NSMutableDictionary *) newDict
    {
        [aDict autorelease];
        [newDict retain];
        aDict = newDict;
    }

    - (void) setADict: (NSMutableDictionary *) newDict
    {
      if (aDict != newDict) {
        [aDict release];
        [newDict retain];
        aDict = newDict;
      }
    }

    - (void) setADict: (NSMutableDictionary *) newDict
    {
        [newDict retain];
        [aDict release];
        aDict = newDict;
    }

Yo diría que el tercero es más simple, el segundo es más rápido con el tiempo, y el primero es meh . El primero abarrotará sus grupos de autorelease (lo que puede o no llevar a la acumulación de memoria). El segundo y el tercero son equivalentes en términos de seguridad y gestión de memoria de propiedad. Sin embargo, el segundo le ahorrará llamadas de método innecesarias si está configurando el mismo diccionario sobre sí mismo.

Otros consejos

NSMutableDictionary liberará todos los objetos (valores) en el lanzamiento.

NSMutableDictionary copia la clave y el envío se retiene al valor para cada par de clave / valor que agregó. La práctica del cacao es que cuando algo se mantiene como referencia, entonces es responsable de liberarlo.

Consulte la referencia de NSMutableDictionary

  

Métodos que agregan entradas a   diccionarios & # 8212; ya sea como parte de   inicialización (para todos los diccionarios)   o durante la modificación (para mutable   diccionarios) & # 8212; copia cada argumento clave   (Las llaves deben cumplir con el NSCopying   protocolo) y agregue las copias al   diccionario. Cada valor correspondiente   el objeto recibe un mensaje retenido para   Asegúrate de que no se desasignará   antes de que el diccionario termine con   

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top