En mi humilde opinión, qué camino es 'correcto' es una cuestión de preferencia. No estoy en desacuerdo con los respondedores que abogan por no usar autorelease
, pero mi preferencia es usar autorelease
a menos que exista una razón abrumadoramente convincente para no hacerlo. Enumeraré mis razones y podrá decidir si son apropiadas o no a su estilo de programación.
Como señaló Chuck, existe una leyenda semiurbana de que hay algún tipo de sobrecarga en el uso de grupos de autorreleases. Esto no podría estar más lejos de la verdad, y esto viene de incontables horas dedicadas a usar Shark.app para sacar el último rendimiento del código. Intentar optimizar esto se encuentra en el territorio de la "optimización prematura". Si, y solo si, Shark.app te proporciona datos concretos, esto podría ser un problema, incluso si consideras buscarlo.
Como han señalado otros, un objeto liberado automáticamente se "libera en algún momento posterior". Esto significa que se quedan, ocupando la memoria, hasta que ese "punto posterior" rueda. Para la mayoría de los casos, esto se encuentra en la parte inferior de un pase de procesamiento de eventos antes de que el bucle de ejecución duerma hasta el próximo evento (temporizador, usuario que hace clic en algo, etc.).
Ocasionalmente, sin embargo, tendrá que deshacerse de esos objetos temporales más pronto, en lugar de más tarde. Por ejemplo, debe procesar un archivo enorme de varios megabytes o decenas de miles de filas de una base de datos. Cuando esto suceda, deberá colocar un NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
en un punto bien elegido, seguido de un [pool release];
en la parte inferior. Esto casi siempre sucede en algún tipo de "procesamiento por lotes de bucle", por lo que suele ser al principio y al final de algún bucle crítico. Una vez más, esto debe basarse en la evidencia, no en la base del presentimiento. El ObjectAlloc de Instrument.app es lo que utilizas para encontrar estos puntos problemáticos.
La razón principal por la que prefiero autorelease
a release
, sin embargo, es que es mucho más más fácil escribir programas libres de fugas. En resumen, si usted decide ir a la ruta release
, es necesario garantía que release
se envía finalmente a obj
, bajo todos circunstancias. Si bien esto parece que podría ser simple, en realidad es sorprendentemente difícil de hacer en la práctica. Tomar su ejemplo, por ejemplo:
// array is an instance of NSMutableArray
MyClass *obj = [[MyClass alloc] init];
[array addObject:obj];
// Assume a few more lines of work....
[obj release];
Ahora imaginemos que, por alguna razón, algo, en alguna parte, sutilmente viola el supuesto de que array
es mutable, tal vez como resultado de la utilización de algún método para procesar los resultados, y la devuelve array que contiene los resultados procesados fue creado como NSArray
.Cuando envíe addObject:
a ese inmutable NSArray
, se lanzará una excepción y nunca enviará obj
su mensaje release
. O tal vez algo va mal en alguna parte entre el momento en obj
fue alloc
dy el requiere llamada a release
, como se comprueba alguna condición y return()
inmediatamente por error, ya que deslizó su mente que esa llamada a release
más adelante debe tener lugar.
Acaba de filtrar un objeto. Y probablemente se haya registrado durante varios días tratando de descubrir dónde y por qué lo está filtrando. Por experiencia, pasará muchas horas mirando ese código anterior, convencido de que posiblemente no sea la fuente de la fuga porque muy claramente envía obj
a release
. Luego, después de varios días, experimentarás lo que solo se puede describir como una epifanía religiosa a medida que te iluminen con la causa del problema.
Consideremos el caso autorelease
:
// array is an instance of NSMutableArray
MyClass *obj = [[[MyClass alloc] init] autorelease];
[array addObject:obj];
// Assume a few more lines of work....
Ahora, ya no importa lo que pase, porque es prácticamente imposible escapar obj
accidentalmente, incluso en casos de esquina extremadamente inusuales o excepcionales.
Si desea que su código sea absolutamente seguro, se recomienda encarecidamente utilizar la liberación automática: consulte http://stackoverflow.com/questions/1147785/use-autorelease-before-adding-objects-to-a-collection/1149040#1149040. – Casebash