2012-04-12 38 views
21

Es una buena práctica colocar muchos objetos autoreleased en un grupo de liberación automática en acción de bucle. Encontré que alguien puso el @autoreleasepool en bucle, pero otros pusieron el bucle en @autoreleasepool.@autoreleasepool en loop o loop en @autoreleasepool?

1:

while ([rs next]) { 
    @autoreleasepool { 
     NSDictionary *dict = [self dictFromXX]; 
     //... 
    } 
} 

2:

@autoreleasepool { 
    while ([rs next]) { 
     NSDictionary *dict = [self dictFromXX]; 
     //... 
    } 
} 

¿Qué es mejor? o cualquier diferencia entre el código 1 y 2?

Gracias!

+0

bucle debe estar dentro autoreleasepool 2. es correcta – Charan

+0

Tome un vistazo a [Gestión de memoria con el objetivo C/Cacao/iPhone] (http://memo.tv/archive/memory_management_with_objective_c_cocoa_iphone). –

Respuesta

28

En su primer ejemplo para cada iteración se drena el grupo. Esto tiene sentido si el cuerpo de la iteración involucra una gran cantidad de objetos liberados automáticamente.

El segundo ejemplo solo vaciará el grupo una vez después del ciclo.

Por lo tanto, si las partes internas del bucle están causando la hinchazón de la memoria, vaya a la opción uno. Si la acumulación de memoria en todo el ciclo es aceptable, entonces bucle y luego use la opción dos.

1

me gustaría ir para la versión 2.

Un bloque @autoreleasepool dará a conocer todos los objetos que recibieron una autorelease cuando se terminó el bloque. Esto llevará tiempo porque necesitará algunos ciclos de CPU y, según el objeto, el tiempo utilizado puede ser mucho mayor de lo esperado.

Creo que @autoreleasepool personalizado solo tiene sentido cuando se trabaja con muchos datos> 20 MB o se trabaja con datos en un hilo no principal.

So. Recomiendo evitar "corto" @autoreleasepool 's. Porque puede ralentizar tu ejecución.

+0

No lo entiendo, el ciclo total de la CPU para la versión será el mismo porque al final el objeto total que se lanzará es el mismo. ¿Estás hablando de la sobrecarga de la ejecución del control de grupo de liberación automática? No estoy seguro acerca de los gastos generales allí. –

+0

@HelinWang drenar memoria con demasiada frecuencia significa perder ciclos de CPU en NSAutoreleasePool. – Andy

+0

@Andy esto es lo que mi comentario pregunta: ¿por qué va a agotar la memoria con demasiada frecuencia? --- "al final, el objeto total que se lanzará es el mismo" –

3

En el primer ejemplo, autoreleasepool se crea al comienzo de la iteración y se drena y al final de la iteración. En el segundo caso, el grupo se crea una vez y se destruye solo después de que el ciclo ha finalizado. Si usa la segunda variación, puede obtener una gran sobrecarga de memoria ya que todos los objetos liberados automáticamente se liberan solo al final. Sin embargo, debe considerar la cantidad de datos que necesita procesar. En la mayoría de los casos, la segunda variante es más preferida.

0

Depende de cuántos elementos pendientes se lanzarán. Imagen que Autorelease Pool como tu basura, pon algo sin usar y lanzará más tarde.

0

@autoreleasepool bloques son más eficientes que usar una instancia de NSAutoreleasePool directamente; también puede usarlos incluso si no usa ARC.- NSAutoreleasePool Class Reference

Por lo general, no es necesario piscinas autorelease, si lo hace porque está en un bucle y autoreleasing un montón de objetos y luego la opción 1 tiene más sentido que 2 como usted está tratando de evitar el alza que el bucle es creando. El momento de usar la opción 2 es si no hay un conjunto de autorrelease configurado (si está realizando un selector en el fondo, por ejemplo o en +load), pero en realidad debería intentar usar GCD para eso.

En resumen, si no tiene un método muy largo y necesita enrollar un bucle en un grupo de liberación automática, vaya a la opción 1 en la mayoría de los casos. Si se llama al método sin que se haya configurado un grupo de liberación automática, entonces debe ser lo primero el @autorelease.