web-development-kb-es.site

¿Cómo funciona el grupo de ejecución automática de NSAutoreleasePool?

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];
}
94
James Sumners

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.

65
kperryua

NSAutoreleasePool: drenaje frente a liberación

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.

37
mmalc

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í .

17
Neovibrant

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ó.

7
kperryua

Encontré que este enlace daba la mejor explicación sobre cuándo y cómo usar NSAutoReleasePool: AutoReleasePool

1
Wayne Lo

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.

0
Hardik Mamtora

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

0
Antwan van Houdt

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. "

https://developer.Apple.com/library/mac/documentation/cocoa/conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html

0
Gagan_iOS