2010-01-29 10 views
12

En el siguiente ejemplo de código de la Guía de programación de datos básicos, NSFetchRequest se crea con liberación automática mientras NSSortDescriptor no se crea con liberación automática. ¿Por qué no se creó NSSortDescriptor con liberación automática? ¿Es una cuestión de preferencia?Autorelease or Not Autorelease

NSManagedObjectContext *moc = [self managedObjectContext];  
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Employee" 
                inManagedObjectContext:moc]; 

NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease]; 
[request setEntity:entityDescription]; 
// Set example predicate and sort orderings... 
NSNumber *minimumSalary = ...; 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(lastName LIKE[c]'Worsley') AND (salary > %@)", minimumSalary];  
[request setPredicate:predicate]; 
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"firstName" 
                   ascending:YES]; 
[request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]]; 
[sortDescriptor release]; 
NSError *error; 
NSArray *array = [moc executeFetchRequest:request error:&error]; 
if (array == nil){ 
    // Deal with error... 
} 

Respuesta

35

Cuando suelte automáticamente, básicamente está diciendo: "No lo necesito más, pero cualquier otra persona es libre de recogerlo (antes de que se agote el grupo de autodesbloqueo)". Cuando liberas explícitamente un objeto que dices: "No lo necesito más y, a menos que alguien más haya dicho lo contrario (adquirido), debe ser desasignado inmediatamente".

En consecuencia, la liberación automática no suele ser lo incorrecto. Es requerido cuando desea pasar objetos al remitente de un mensaje sin requerir que el remitente se encargue de liberar el objeto.

+1

Esa es la explicación más sucinta que he leído para la liberación automática. – TechZen

+0

¡Muy buena respuesta! +! –

26

Para AutoRelease o no AutoRelease

Eso es la cuestión.

Si es más noble para el codificador sufrir las hondas y flechas de pérdidas de memoria o tomar las armas contra un mar de punteros de referencia y retenerlas, terminarlas ... ¡Es una consumación devotamente deseable! Sí, ahí está el problema! ... Porque en aquellos objetos sobre los que se libera, qué choques pueden surgir cuando hacemos referencia a objetos que no están allí debemos darnos una pausa.

No pude evitarlo. Tomaré el golpe de rep. ¡Me arrepiento de nada!

+0

+0: ya tienes cuatro puntos de este :) –

+0

+1: Absolutamente brillante. –

+0

Divertido, pero se interpone cuando se busca la respuesta real. – finnw

0

La pregunta es: ¿cómo afecta el uso de autorelease o release a la vida útil de un objeto?

En sus dos ejemplos no hace ninguna diferencia.

Tanto NSFetchRequest como NSSortDescriptors estarán activos hasta el final del método, independientemente de si se lanzan o se vuelven a publicar automáticamente.

Si crea una instancia de un objeto y luego se lo da a otro objeto (por ejemplo, un NSArray), permanecerá activo independientemente de si llama al lanzamiento o a la liberación automática.

-1

Tanto retener y autorelease, funcionalmente retener un objeto, sino no se combinan. La diferencia es que los recuentos de retenciones solo pueden ser decrementados por otro objeto, mientras que los recuentos autoemitidos se disminuyen automáticamente cuando se vacía el NSAutoreleasePool. Si ningún otro objeto ha retenido el objeto liberado automáticamente en el momento en que la agrupación se vacía, se dispara.

Básicamente, usa la liberación automática cuando desea asegurarse de que un objeto se cuelga en el método actual y se puede pasar a otros objetos, pero no desea tener que rastrear su liberación usted mismo.

En su código de ejemplo, la liberación automática es solo una medida de seguridad. El objeto NSPredicate se libera porque su trabajo está terminado, pero el codificador quería asegurarse de que el objeto NSFetchRequest quedara colgado. No tiene que usar "liberación automática" en esta instancia, pero si perdió el conteo de sus lanzamientos, fetchRequest podría desaparecer.Por otro lado, no lo quiere huérfano y con fugas, por lo que usa la liberación automática para limpiar cuando el grupo está en desagües.

El uso más común de la liberación automática es cuando crea un número variable de objetos cada vez. No desea tener que rastrearlos a todos para poder soltarlos y dejar que el grupo los cumpla. (Aún mejor, creas un grupo local y lo drenas tan pronto como hayas terminado.)

En el estándar Apple API, cualquier método que crea un nuevo objeto sin las palabras clave 'init', 'new' o 'create 'devuelve un objeto liberado automáticamente.

-[NSString initWithString:] no se autorrelease pero - [NSString stringWithString:] es. Esto causa problemas en entornos de recolección que no son de basura porque stringWithString: devuelve una cadena que parece comportarse como un objeto retenido pero luego desaparecerá de forma aparentemente aleatoria cuando el grupo de liberación automática se creó en los desagües.


Edit01: De la Manzana Docs

piscina autorelease es una instancia de NSAutoreleasePool que “contiene” otros objetos que han recibido un mensaje de autorelease; cuando el grupo de autorretención se desasigna, envía un mensaje de liberación a cada uno de los objetos . Un objeto se puede poner en un grupo de liberación automática varias veces , y recibe un mensaje de liberación por cada vez que se puso en el grupo . Por lo tanto, el envío de autorelease en lugar de la liberación a un objeto se extiende la vida útil de dicho objeto en menos hasta la piscina en sí es liberado (el objeto puede sobrevivir más tiempo si se retiene en la provisional).

Los recuentos de retención y liberación automática mantienen un objeto vivo por el mismo mecanismo de conteo básico (pero separado). La principal diferencia es qué objeto propietario envía el lanzamiento. Con conteos retenidos, es otro objeto, pero para un recuento autorellenado es el grupo de autorrelease.

+0

autorelease NO conserva un objeto. –

+0

Aclaré, ¿es eso mejor? – TechZen

1

El objeto de solicitud se devolverá a la persona que llama, mientras que sortDescriptor se utiliza y luego se descarta.

La justificación para la liberación automática es simple. Sin él, cualquier objeto devuelto por una función debería ser liberado por la persona que llama si no lo necesita. El uso de la liberación automática significa que las funciones pueden devolver un objeto que si a la persona que llama no le importa, o si lo van a ver pero no a una referencia, entonces pueden usarlo sin agregar código adicional para liberarlo. Solo si mantienen una referencia, deben retenerla.

Vale la pena pensar exactamente qué significa liberación automática. Cuando llamas a autorrelease sobre un objeto, agrega el objeto a una lista, y cuando termina tu bucle de aplicación, tendrá un lanzamiento llamado sobre él. Esto hace que la liberación automática sea exactamente equivalente a una versión retrasada.

El documento de Apple sobre la gestión de la memoria es excelente y merece una lectura cuidadosa. http://developer.apple.com/iPhone/library/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html

Cuestiones relacionadas