Como lo entiendo, cualquier cosa creada con alloc , new , o copy necesita ser liberada manualmente. Por ejemplo:
int main(void) {
NSString *string;
string = [[NSString alloc] init];
/* use the string */
[string release];
}
Mi pregunta, sin embargo, ¿no sería esto tan válido ?:
int main(void) {
NSAutoreleasePool *pool;
pool = [[NSAutoreleasePool alloc] init];
NSString *string;
string = [[[NSString alloc] init] autorelease];
/* use the string */
[pool drain];
}
Sí, tu segundo fragmento de código es perfectamente válido.
Cada vez que se envía un autor a un objeto, se agrega al grupo de autorelease más interno. Cuando la agrupación se agota, simplemente envía, por favor, a todos los objetos de la agrupación.
Los grupos de autorelease son simplemente una conveniencia que le permite aplazar el envío hasta "más tarde". Ese "más tarde" puede suceder en varios lugares, pero el más común en las aplicaciones de la interfaz de usuario de Cocoa es al final del ciclo de ciclo de ejecución actual.
Dado que la función de drain
y release
parece estar causando confusión, vale la pena aclarar aquí (aunque esto está cubierto en la documentación ...).
Estrictamente hablando, desde la perspectiva del panorama general drain
es no equivalente a release
:
En un entorno de referencia, drain
realiza las mismas operaciones que release
, por lo que las dos son equivalentes en ese sentido. Para enfatizar, esto significa que debes no filtrar un grupo si usas drain
en lugar de release
.
En un entorno de recolección de basura, release
es un no-op. Por lo tanto no tiene efecto. drain
, por otro lado, contiene una sugerencia para el recolector que debe "recopilar si es necesario". Por lo tanto, en un entorno de recolección de basura, el uso de drain
ayuda al sistema a equilibrar los barridos de recolección.
Como ya se señaló, su segundo fragmento de código es correcto.
Me gustaría sugerir una forma más sucinta de utilizar el grupo de autorelease que funciona en todos los entornos (recuento de ref, GC, ARC) y también evita la confusión de descarga/descarga:
int main(void) {
@autoreleasepool {
NSString *string;
string = [[[NSString alloc] init] autorelease];
/* use the string */
}
}
En el ejemplo anterior, tenga en cuenta el bloque @autoreleasepool . Esto está documentado aquí .
No, tu estas equivocado. La documentación indica claramente que, en el caso de no-GC, -drain es equivalente a -release, lo que significa que NSAutoreleasePool se no se filtró.
Encontré que este enlace daba la mejor explicación sobre cuándo y cómo usar NSAutoReleasePool: AutoReleasePool
el envío de autorelease en lugar de soltarlo a un objeto prolonga la vida útil de ese objeto al menos hasta que la agrupación se drene (puede ser más largo si el objeto se retiene posteriormente). Un objeto se puede colocar en el mismo grupo varias veces, en cuyo caso recibe un mensaje de liberación por cada vez que se colocó en el grupo.
sí, tu código es perfecto. Si estuvieras usando un recolector de basura, sería suficiente para establecer la cadena en cero cuando hayas terminado. La recolección de basura no es buena para el rendimiento de su aplicación, así que no recomendaría su uso: P
Lo que leí de Apple: "Al final del bloque de agrupación de liberación automática, los objetos que recibieron un mensaje de liberación automática dentro del bloque reciben un mensaje de liberación; un objeto recibe un mensaje de liberación por cada vez que recibió un mensaje de liberación automática dentro del bloque. "