Objetivo C: asignar, copiar, retener

83

Soy nuevo en el Objetivo C. Tengo conocimientos básicos en C, incluido el concepto de punteros. Tengo dos preguntas básicas:

  1. ¿Alguien puede explicar la diferencia entre asignar, copiar y retener con alguna analogía?
  2. ¿Cómo maneja una función que devuelve una variable de puntero y cómo realiza la mensajería a través de un puntero de retorno?
Sabha B
fuente

Respuestas:

126

Respuesta actualizada para documentación modificada

La información ahora se distribuye en varias guías de la documentación. Aquí hay una lista de lecturas obligatorias:

La respuesta a esta pregunta ahora depende completamente de si está utilizando una aplicación administrada por ARC (el predeterminado moderno para nuevos proyectos) o si está forzando la administración manual de memoria.

Asignar frente a débil : use asignar para establecer el puntero de una propiedad a la dirección del objeto sin retenerlo o curarlo de otra manera; use débil para que la propiedad apunte automáticamente a cero si el objeto que se le asignó se desasignó. En la mayoría de los casos, querrá usar débil para no intentar acceder a un objeto desasignado (acceso ilegal a una dirección de memoria - " EXC_BAD_ACCESS") si no realiza una limpieza adecuada.

Retener frente a Copiar : las propiedades declaradas usan retener de forma predeterminada (por lo que simplemente puede omitirlo por completo) y administrará el recuento de referencias del objeto automáticamente si otro objeto está asignado a la propiedad o si está establecido en cero; Use copiar para enviar automáticamente un -copymensaje al objeto recién asignado (que creará una copia del objeto pasado y asignará esa copia a la propiedad en su lugar; es útil (incluso necesario) en algunas situaciones en las que el objeto asignado podría modificarse después de haber sido configurado como una propiedad de algún otro objeto (lo que significaría que la modificación / mutación también se aplicaría a la propiedad).

Joshua Nozzi
fuente
2
Gracias amigo, leí los conceptos básicos de Apple Dev, sobre mi desarrollo actual. Tener dificultades en la gestión de la memoria "se bloqueó en objc_msgSend ()" Así que pensé en revisar mi comprensión de las propiedades. stackoverflow.com/questions/4506205/…
Sabha B
2
Solo un aviso, el enlace a la respuesta va a una "Página no encontrada" genérica en el sitio de Apple. Luego, redirige a la "Biblioteca de desarrolladores de Mac". Esta respuesta SO tiene información útil: stackoverflow.com/questions/2255861/…
hippeelee
1
Algo difícil de actualizar porque la documentación ha cambiado y ya no está en un lugar conveniente. Comentarios enviados al equipo de documentación de Apple.
Joshua Nozzi
33

La Guía de programación de administración de memoria de la Biblioteca de referencia de iOS tiene conceptos básicos de asignación, copia y retención con analogías y ejemplos.

copiar Hace una copia de un objeto y lo devuelve con un recuento de retención de 1. Si copia un objeto, es propietario de la copia. Esto se aplica a cualquier método que contenga la palabra copia, donde "copia" se refiere al objeto que se devuelve.

retener Aumenta el recuento de retención de un objeto en 1. Toma la propiedad de un objeto.

release Disminuye el recuento de retención de un objeto en 1. Renuncia a la propiedad de un objeto.

Larry Hipp
fuente
Gracias por su respuesta. ¿Podría explicarnos que 1.ClassA tiene una propiedad llamada - (Class B *) functionName; 2.ClassB tiene método - (void) setHeight; 3.Interfaz ClassC He declarado ClassA * tempA como retener. 4. Implementación de clase C en el constructor Tengo esta declaración ClassB * tempB = tempA.functionName; 5. Cuando intento enviar un mensaje (tempB. SetHeight;) en la siguiente línea de inicialización de tempB, mi programa funciona bien.
Sabha B
6.Poner la misma declaración (tempB. SetHeight;) en alguna función y llamar a la misma función, mi programa se bloquea en objc_msgSend ().
Sabha B
8
NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:@"First",@"Second", nil];
NSMutableArray *copiedArray = [array mutableCopy];
NSMutableArray *retainedArray = [array retain];

[retainedArray addObject:@"Retained Third"];
[copiedArray addObject:@"Copied Third"];

NSLog(@"array = %@",array);
NSLog(@"Retained Array = %@",retainedArray);
NSLog(@"Copied Array = %@",copiedArray);

array = (
    First,
    Second,
    "Retained Third"
)
Retained Array = (
    First,
    Second,
    "Retained Third"
)
Copied Array = (
    First,
    Second,
    "Copied Third"
)
srivas
fuente
2
Una explicación circundante mejoraría seriamente su respuesta.
zx485
4
  1. asignar

    • asignar es un atributo de propiedad predeterminado
    • asignar es un atributo de propiedad que le dice al compilador cómo sintetizar la implementación del setter de la propiedad
  2. Copiar:

    • se requiere copia cuando el objeto es mutable
    • copy devuelve un objeto que debe liberar explícitamente (por ejemplo, en dealloc) en entornos no recolectados de basura
    • debe liberar el objeto cuando termine con él porque está reteniendo la copia
  3. conservar:

    • especifica que el nuevo valor debe enviarse "-retain" en la asignación y el valor anterior debe enviarse "-release"
    • si escribe, retener, funcionará automáticamente como fuerte
    • Los métodos como "alloc" incluyen un "retener" implícito
Chen Rui
fuente