Bloques de albercas autorelease de iOS

Estaba leyendo la documentation de Apple sobre la gestión de la memory cuando pude autorizar bloques de grupo y algo me hizo pensar.

Any object sent an autorelease message inside the autorelease pool block is released at the end of the block. 

No estoy seguro de entenderlo completamente. Cualquier object creado dentro de un bloque de agrupación de autorelease se libera al final del bloque de todos modos porque esa es su vida útil. ¿Por qué tendría que llamar a la autorización automática del object cuando se lanzará de todos modos cuando llegue al final del bloque?

Para ser más claro, daré un ejemplo de lo que estoy pensando:

  @autoreleasepool { MyObject *obj = [[MyObject alloc] init]; // no autorelease call here /* use the object*/ //.... // in the end it should get deallocated because it's lifespan ends, right? // so why do we need to call autorelease then?! } 

PD: Por favor, no me digas que debido a ARC no necesitamos hacer algunas cosas porque ARC se encarga de ellas. Soy plenamente consciente de eso, pero quiero dejar ARC a un lado por solo unos minutos para comprender el mecanismo de la gestión de la memory.

Autorelease simplemente elimina un recuento de retención del object que no "libera" la memory inmediatamente como en c. Cuando el set de autorelease finaliza, todos los objects liberados automáticamente con un recuento de 0 tendrán su memory liberada.

A veces creas muchos objects. Un ejemplo sería un bucle que está creando nuevas cadenas cada vez que itera y agrega nuevos datos a la cadena. Puede que no necesites las versiones anteriores de la cadena y querrás liberar memory utilizada por ellas. Puede lograr esto utilizando explícitamente el grupo de autorelease en lugar de esperar a que se realice de forma natural.

 //Note: answers are psudocode //Non Arc Env @autoreleasepool { MyObject *obj = [[MyObject alloc] init]; // no autorelease call here //Since MyObject is never released its a leak even when the pool exits } //Non Arc Env @autoreleasepool { MyObject *obj = [[[MyObject alloc] init] autorelease]; //Memory is freed once the block ends } // Arc Env @autoreleasepool { MyObject *obj = [[MyObject alloc] init]; //No need to do anything once the obj variable is out of scope there are no strong pointers so the memory will free } // Arc Env MyObject *obj //strong pointer from elsewhere in scope @autoreleasepool { obj = [[MyObject alloc] init]; //Not freed still has a strong pointer } 

(Sobre todo dando un poco de información adicional; @ Kibitz503 te está dando la respuesta correcta.)

 @autoreleasepool { MyObject *obj = [[MyObject alloc] init]; // no autorelease call here /* use the object*/ //.... // in the end it should get deallocated because it's lifespan ends, right? // so why do we need to call autorelease then?! } 

PD: Por favor, no me digas que debido a ARC no necesitamos hacer algunas cosas porque ARC se encarga de ellas. Soy plenamente consciente de eso, pero quiero dejar ARC a un lado por solo unos minutos para comprender el mecanismo de la gestión de la memory.

Bien, no consideremos ARC. En lo anterior, sin ARC, obj no sería desasignado. Solo porque ARC agrega llamadas de release adicionales posiblemente se desasigne (dado su ejemplo, en realidad no tenemos idea, ya que no sabemos qué sucede en el use the object ).

Como explica @ Kibitz503, "lanzamiento" no significa "desasignar". Al final del bloque, el set de autorelease drena, lo que significa que cualquier llamada de autorelease pendiente se envía como release al final del bloque. Si eso lleva a que el object scope un 0 retenga el conteo, entonces se desasigna.

Pero si lo anterior está en un bloque o no, sin ARC es una fuga.

Las agrupaciones autorelease diferencian la liberación del object hasta el final del grupo, lo que evita la posibilidad de que se libere antes de que llegue al final. Entonces, básicamente, es asegurarse de que el object no se liberará antes del final del grupo.