2011-10-18 9 views
7

que estaba leyendo los documentos ARC en el sitio llvm: http://clang.llvm.org/docs/AutomaticReferenceCounting.html#autoreleasepoolsemántica @autoreleasepool

..en particular acerca @autoreleasepool.

En gran parte de la implementación actual usando NSAutoreleasePool, veo casos en los que el grupo se agota periódicamente durante una iteración de ciclo. ¿Cómo hacemos lo mismo con @autorelease pool, o todo se hace de alguna manera bajo el capó?

En segundo lugar, los documentos indican que si se lanza una excepción, el grupo no se vacía ... ok las excepciones son excepcionales por su nombre, pero si ocurren, es posible que desee recuperarlas sin perder una carga de memoria . Los documentos no especifican cuándo se lanzarán estos objetos.

¿Alguien tiene alguna información sobre estos puntos?

Respuesta

9

En muchos de implementación actual usando NSAutoreleasePool, veo los casos en que se drena periódicamente la piscina durante una iteración de bucle - ¿cómo lo hacemos lo mismo con la piscina @autorelease, o es todo hecho por nosotros de alguna manera bajo el capó ?

De la misma manera, es decir, mediante grupos de liberación automática en cascada. Por ejemplo:

@autoreleasepool { 
    … 
    for (int i = 0; i < MAX; i++) { 
     @autoreleasepool { 
      … 
     } 
    } 
    … 
} 

En segundo lugar, los documentos afirman que si se produce una excepción, la piscina no se drena .... ok excepciones son por su nombre excepcional, pero si llegan a suceder, que le gustaría para recuperar sin perder una carga de memoria. Los documentos no especifican cuándo se lanzarán estos objetos.

En la mayoría de los casos, el programa no podrá recuperarse correctamente debido a la naturaleza peculiar de las excepciones en Cocoa, por lo que diría que la fuga de objetos es un problema menor. Si se sale de un bloque @autoreleasepool debido a una excepción, los objetos liberados automáticamente correspondientes solo se liberarán cuando se salte uno de los grupos de autorrelease que lo rodean. Pero puede, por supuesto, colocar los bloques @try/@catch/@finally dentro del bloque @autoreleasepool para evitar que esto suceda.

+0

Creo que la segunda parte de su respuesta no es del todo correcta. los grupos de autorelease se autorellevan de manera efectiva en el grupo de autorrelease que estaba en vigencia cuando se asignaron. Siempre que la excepción no se propague más allá del grupo de autorrelease más externo, ningún objeto liberado automáticamente tendrá fugas. – JeremyP

+0

@Jer Tienes razón; ¡gracias por la advertencia! –

+0

@Bavarious - Gracias por una excelente respuesta. Es seguro, filtra la memoria en bucle mientras usa 'stringWithFormat'. –

2

cómo hacemos lo mismo con la piscina @autorelease

De esta manera:

for (int i = 0; i < 10000; i++) { 
    @autoreleasepool { 
     // Do your work here 
     ... 
    } 
} 

En segundo lugar, los documentos afirman que si se produce una excepción, el isn de la piscina' t drenado ... bien, las excepciones son excepcionales por su nombre, pero si ocurren, es posible que te guste recuperarlas sin perder una gran cantidad de memoria.

AFAIK esto no es posible con ARC. ARC no es excepcionalmente seguro. Si se produce una excepción, existe la posibilidad de pérdidas de memoria no recuperables. El código que usa ARC no debe basarse en excepciones para informes de errores. La expectativa es que el proceso se bloquee de todos modos cuando se produce una excepción.