Soy nuevo en objective-c, y conozco las reglas básicas de administración de memoria como cuándo retain
release
autorelease
. Pero no sé cuándo debo envolver mi código en el grupo de autorrelease y por qué?cuándo debo envolver mi código en el grupo de liberación automática
Respuesta
Al igual que con otras optimizaciones de rendimiento, generalmente solo debe agregar grupos de autorelease adicionales a su código si observa un alto uso de memoria y perfiles (utilizando Instruments, por ejemplo) lo lleva a pools de autorelease adicionales como solución.
Dicho esto, puede ajustar el código que crea una gran cantidad de objetos temporales en un circuito cerrado en un grupo de autorrelease. El grupo de autorrelease predeterminado se drena al final de un ciclo de ciclo de ejecución. Por lo tanto, si está creando muchos objetos temporales en cada iteración de un bucle for en su código, el grupo de autorrelease predeterminado no se agotará hasta que se haya ejecutado todo el ciclo, lo que significa que todos los objetos temporales que crea pueden sumar hasta un alto uso de memoria temporal (a veces llamado "marca de agua alta"). Puede envolver cada iteración del ciclo en @autoreleasepool
para hacer que los objetos temporales innecesarios, lanzados automáticamente en esa iteración de ciclo se lancen antes.
Todos los objetos liberados automáticamente se colocan dentro de un grupo de autorrelease. Por lo general, hay uno predeterminado creado dentro de su función principal. En cuanto a envolver objetos dentro de un grupo de autorrelease no predeterminado, normalmente se realiza como una optimización.
Normalmente no es necesario utilizar un grupo de autorrelease explícito porque el grupo de autorrelease predeterminado se drena automáticamente dentro del ciclo de ejecución de su aplicación. Sin embargo, si tiene una aplicación que crea muchos objetos liberados automáticamente antes de que regrese de sus manejadores de eventos, puede usar mucha memoria para esos objetos. Por lo tanto, si ajusta su código dentro de un grupo de autorrelease explícito, los objetos liberados automáticamente se colocarán allí en lugar del grupo predeterminado. Esto le permite vaciar periódicamente este grupo para evitar la acumulación de objetos liberados automáticamente.
Para amplía las respuestas anteriores:
Una piscina de liberación automática se utiliza para enviar un mensaje release
automáticamente a los objetos añadidos a la misma.
En un programa iOS o Cocoa, se crea automáticamente un grupo de autorrelleno en el hilo principal y se drena al final del ciclo de ejecución.
Dicho esto, un grupo de autorrelleno es obligatorio cuando se utilizan objetos de autodesbloqueo en otro hilo.
Por lo tanto, si separa un hilo de algún método, envuelva el código enhebrado dentro de un grupo de autorrellenos. De lo contrario, los objetos de autodesbloqueo creados en el hilo solo tendrán fugas.
Otro uso de un grupo de autodispensas es la optimización de partes del código que utilizarán mucha memoria, por lo que se liberan antes del final del ciclo de ejecución.
Pero solo se trata de objetos de liberación automática.
Por ejemplo:
- (void)test
{
NSMutableArray * a = [ [ NSMutableArray alloc ] init ];
[ a release ];
}
No hay necesidad de una piscina de liberación automática aquí, ya que no tiene un objeto de auto-editado.
La variable a
se liberará inmediatamente, ya que se asignó y liberará explícitamente.
Ahora esto:
- (void)test
{
NSMutableArray * a = [ NSMutableArray arrayWithCapacity ];
}
Aquí está utilizando un constructor de conveniencia, lo que significa que no tiene la propiedad de ese objeto.
También significa que el objeto se agregó al grupo de autodispensas actual (si hay uno).
por lo que será liberado cuando se drena esta piscina de liberación automático, por lo que podría tomar algunos ciclos ...
Si la parte del código que está escribiendo utiliza una gran cantidad de memoria, es posible utilizar otro piscina autorelease, por lo que sus objetos de auto-editado son liberados cuando sus devuelve el método:
- (void)test
{
@autoreleasepool
{
NSMutableArray * a = [ NSMutableArray arrayWithCapacity ];
}
}
Hay, sin embargo, tres ocasiones en las que podría utilizar sus propios bloques de la piscina autorelease:
Si está escribiendo un programa que no está basado en un marco de interfaz de usuario, como una herramienta de línea de comandos.
Si escribe un bucle que crea muchos objetos temporales. Puede utilizar un bloque de agrupación de autorrelease dentro del ciclo para eliminar esos objetos antes de la próxima iteración. El uso de un bloque de agrupación de autorrelease en el bucle ayuda a reducir la huella de memoria máxima de la aplicación.
Si genera un hilo secundario.
- 1. ¿Cuándo se produce la liberación automática en Cocoa Touch?
- 2. ¿Debo siempre envolver mi código en intentar ... atrapar bloques?
- 3. ¿Cuándo se lanza un objeto con 'liberación automática'?
- 4. ¿Qué sucede cuando se ejecuta el siguiente código? Ball * ball = [[[Ball alloc] init] liberación automática] liberación automática];
- 5. ¿debo envolver todo mi código de servicio WCF en un bloque try catch?
- 6. ARC equivalente a la liberación automática?
- 7. error 'liberación automática' no está disponible: no disponible en el modo de conteo de referencia automática
- 8. ¿Puedo liberar anticipadamente un objeto de liberación automática?
- 9. ¿Cuándo el compilador optimiza mi código
- 10. ¿Debo usar @ en mi código PHP?
- 11. NIF para envolver mi código C++ multi-threaded
- 12. Gestión de memoria Objective-C (asignación y liberación automática)
- 13. ¿Cuándo debo cambiar el serialVersionUID?
- 14. Segregando el código de depuración y liberación en C#
- 15. ¿Debo usar identificadores de bloque ("end;") en mi código?
- 16. ¿Por qué las plantillas main.m de iOS incluyen una declaración de devolución y un grupo de liberación automática?
- 17. ¿Cuál es el punto en un retener inmediatamente seguido de una liberación automática?
- 18. ¿Cuándo debo especificar el protocolo de JavaScript?
- 19. ¿Cuándo debo usar adornos?
- 20. WPF Altura automática en el código
- 21. ¿Cuándo debo declarar session_start() ;?
- 22. ¿Cuándo debo usar cuaterniones?
- 23. ¿Utilizar la liberación automática al establecer una propiedad de retención usando la sintaxis de punto?
- 24. ¿Cómo puedo envolver un grupo de elementos adyacentes usando XSLT?
- 25. Cuándo usar el grupo de subprocesos en C#?
- 26. ¿Cómo debo usar el modo de depuración/liberación en Visual Studio?
- 27. ¿Cuándo debo protegerme contra el nulo?
- 28. ¿Cómo debo mover mi código de dev a producción?
- 29. ¿Cuándo debo usar malloc en C y cuándo no?
- 30. ¿Está tratando de envolver el código de exceso aceptable?
Me salvaste. Tengo un método de cálculo de larga ejecución que crea muchos números en varios bucles. En los instrumentos, el uso de la memoria aumenta tremendamente y disminuye una vez que finaliza el cálculo. ¿Hay algún inconveniente al usar '@ autorelease' para envolver bucles individuales? Apple no lo recomienda realmente, ¿verdad? – JFS
Es recomendado por Apple en los casos en que sea apropiado. Consulte la documentación aquí: https://developer.apple.com/library/ios/DOCUMENTATION/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html –
Andrew, ¡eres simplemente increíble! Tuve un dolor de cabeza debido a ese problema de memoria hasta que encontré esa sugerencia. Es simple y funciona simplemente increíble. Incluso puedo permitir más cálculos en mi aplicación ahora. ¡GRACIAS! – JFS