ios multithreading cocoa-touch nsautoreleasepool

ios - Usando ARC, ¿es fatal no tener un grupo de autorelease para cada hilo?



multithreading cocoa-touch (2)

Considere como mínimo un error de programador si no crea un grupo de autorelease para su nuevo hilo. Si eso es fatal para su programa está definido por la implementación de su programa. El problema clásico son los objetos filtrados y, por consiguiente, el dealloc objetos que nunca se ejecuta (podría ser fatal).

La forma moderna de crear un grupo de autorelease bajo ARC es:

void MONThreadsEntry() { // << entry is e.g. a function or method @autoreleasepool { ...do your work here... } }

Más detalladamente, los grupos de autorelease se comportan como pilas de subprocesos locales: puede empujar y abrir, pero siempre debe haber uno en su lugar antes de que se lancen automáticamente todos los elementos de ese hilo. Los mensajes de autorelease no se transfieren de un hilo a otro.

Es posible que no vea problemas (p. Ej., En la consola o fugas) si su idea de "crear un subproceso" está utilizando un mecanismo asíncrono de nivel superior, como el uso de un NSOperationQueue, o si la implementación subyacente crea un subproceso secundario y su propio grupo de autorelease .

De todos modos, en lugar de adivinar cuándo crear grupos de autorelease, simplemente aprenda dónde necesita crearlos y cuándo debe crearlos. Todo está bien definido: no hay necesidad de conjeturas y no hay por qué temer crearlas.

De manera similar, nunca necesitará crear un grupo de autorelease para su hilo si está usando abstracciones de nivel inferior, y nunca objetos de autorelease en ese hilo. Por ejemplo, pthreads y las implementaciones de C pura no necesitarán molestarse con los grupos de autorelease (a menos que alguna API que use asuma que están en su lugar).

Incluso el hilo principal en una aplicación de Cocoa necesita un grupo de autorelease, simplemente no es algo que se escribe porque existe en las plantillas del proyecto.

Actualización - Colas de despacho

En respuesta a la pregunta actualizada: Sí, aún debe crear grupos de autorelease para sus programas que se ejecutan en colas de despacho: tenga en cuenta que con una cola de despacho, no está creando subprocesos, por lo que esta es una pregunta muy diferente de la pregunta original. La razón: aunque las colas de envío administran los grupos de autorelease, no se garantiza el tiempo / punto en que se vacían. Es decir, sus objetos se liberarían (en algún momento), pero también debería crear grupos de liberación automática en este contexto porque la implementación podría (en teoría) drenar el grupo cada 10,000 bloques que se ejecutan, o aproximadamente cada día. Por lo tanto, en este contexto, solo es fatal en situaciones como cuando terminas consumiendo demasiada memoria o cuando tus programas esperan que sus objetos se destruyan de alguna manera determinada, por ejemplo, puedes cargar o procesar imágenes en el fondo y el consumo de memoria consumen una tonelada de memoria si la vida de esas imágenes se prolonga de forma inesperada debido a los conjuntos de autorelease. El otro ejemplo son los recursos compartidos u objetos globales, donde podría responder a notificaciones o introducir condiciones de carrera porque sus objetos "locales" pueden vivir mucho más de lo que espera. También recuerde que la implementación / frecuencia es libre de cambiar según lo consideren adecuados sus implementadores.

Leo esto:

Si alguna vez crea un subproceso secundario en su aplicación, debe proporcionarlo con su propio grupo de autorelease. Los grupos de autorelease y los objetos que contienen se discuten más adelante en

en el libro de cocina de iOS 5 Developer.

Estoy compilando con ARC. He estado creando muchos subprocesos de fondo, y parece que lo estoy haciendo bien. Ninguno de mis hilos de fondo son de larga duración. ¿Se liberarán todos esos objetos, por ejemplo, el grupo de autorelease del hilo principal? ¿O que?

Esto es lo que hago para llamar hilo de fondo:

+(void)doBackground:(void (^)())block { //DISPATCH_QUEUE_PRIORITY_HIGH //dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0), ^{ dispatch_async(dispatch_get_global_queue(-2,0), ^{ block(); }); }

¿Debo cambiar eso a

+(void)doBackground:(void (^)())block { //DISPATCH_QUEUE_PRIORITY_HIGH //dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0), ^{ dispatch_async(dispatch_get_global_queue(-2,0), ^{ @autoreleasepool{ block(); } }); }


Parece que ahora el grupo de autorelease se crea para nuevos hilos automáticamente. No sé cuándo ha cambiado esto y por qué la documentación dice lo contrario, pero eso es todo.