2011-08-30 12 views
5

Después de hacer una prueba de perfil largo, descubrí que en uno de mis archivos ".m" se produce una pérdida de memoria en la sección viewdidload. Lo comprobé y el xcode destacó la parte donde he inicializado arrays de selector con valores. mi programa usa selectores para la entrada del usuario. y tengo 3 5 vistas diferentes en mi programa. el primero es un descargo de responsabilidad, el segundo es un menú donde el usuario puede elegir el tipo de cálculo que quiere hacer. cada cálculo requiere ciertas entradas que el usuario ingresa desde un selector. por ej. una de las vistas tiene 5 entradas que son manejadas por 5 uipickers diferentes con arreglos separados para contener los valores. estas matrices se inicializan con los valores en el método viewdidload de esa vista. aquí es lo que encontré después de ejecutar la prueba:¿Cómo soluciono una pérdida de memoria?

-viewDidLoad .................................. .................................................. ...............

instantiation

Esto está desarrollando la primera vez que una aplicación y estoy un poco confundido acerca de qué hacer. Cualquier ayuda sería apreciada.

+2

Me duelen los ojos = ( –

Respuesta

4

Los objetos en el objetivo c tienen un recuento de retención. Si este conteo de retenciones es mayor que 0 cuando el objeto sale del alcance (cuando deja de usarlo), tiene fugas.

Los siguientes factores incrementan la cuenta de retención

  • [[alloc] init]
  • nueva
  • copia
  • [retener]
  • añadir un objeto a un array
  • añadiendo un objeto como un niño (por ejemplo, vistas)
  • Es probable que haya más, pero usted no aparecerá utilizar cualquier otros en su código

La siguiente disminución del retener recuento

  • [versión]
  • la eliminación de un objeto a partir de una matriz
  • si dealloc una matriz, la totalidad de su los objetos se liberan

Debe revisar su código y asegurarse de que cada una de las retenciones o adiciones a una matriz coincidan con un corresponin g lanzamiento. (Puede liberar variables miembro en el método dealloc).

EDIT: Jeremy hizo un punto válido que mi respuesta no

Una vez que se agrega un objeto a una matriz, se necesita la propiedad y dará a conocer el objeto cuando se hace con ella. Todo lo que necesita hacer es asegurarse de liberar todo lo que tenga de acuerdo con las reglas de administración de memoria

También hay objetos de liberación automática; consulte este ejemplo;

-(init){ 
    ... 
    stagePickerArray = [[NSMutableArray alloc] init]; 
    for (int i = 0; i < 3; i++) 
    { 
     //this string is autoreleased, you don't have call release on it. 
     //methods with the format [CLASS CLASSwithsomething] tend to be autorelease 
     NSString *s = [NSString stringWithFormat:@"%d", i); 
     [stagePickerArray addObject:s]; 
    } 
    ... 
} 

Creo que la única cosa que se echa en falta es un llamado a liberar en su método dealloc

-(void) dealloc 
{ 
    [stagepickerarray release]; //Do this for each of your arrays 
    [super dealloc]; 
} 
+1

Lo sentimos, pero esto es engañoso. No es necesario que coincida con una adición a una matriz con una versión. Una vez que agregue un objeto a una matriz, asumirá la propiedad y lo liberará cuando haya terminado. Todo lo que necesita hacer es asegurarse de ** liberar cualquier cosa que tenga ** de acuerdo con las reglas de administración de memoria. – JeremyP

+0

Editado con una cita de su comentario para aclarar –

+0

Muchas gracias :). Volví y me aseguré de que todos los objetos que retuviera se soltaran correctamente, como campos de texto, selectores, barras de herramientas, etc. También agregué un lanzamiento para cada una de las matrices y luego volví a ejecutar la prueba. Esta vez no hay pérdidas de memoria. Sin embargo, tengo una pregunta, durante la prueba también verifiqué las asignaciones y los bytes totales fueron 9.3mb y los bytes vivos fueron 1.7 mb. ¿Eso es normal? o debería estar preocupado? – cyberbemon

0

En Objective-C necesita ocuparse del conteo de retención de la memoria asignada. Si no lo necesitas -> libéralo.

Siempre que un objeto alloc, devolverá un objeto con retener count = 1.

Mediante el uso de retener, la cuenta de retención se incrementa, mediante el uso de la liberación, la cuenta de retención consigue decrementa. Siempre que el conteo de retención sea igual a 0, el objeto será destruido.

Por lo tanto, siempre que desee utilizar el objeto en otro lugar, debe conservarlo. Así que se asegura de que el objeto no se elimine después de que la otra 'persona' (o lo que sea que haya usado;)) se llame release.

Esta fue una descripción muy, muy corta. Consulte la siguiente guía Memory Management Guide for iOS.

(también desea leer algo sobre ARC - automático Conserve Conteo - que es nuevo en IOS5 ios5 best practice release retain

+0

Gracias :). Echaré un vistazo a eso! . Actualmente estoy usando iOS 4 xD – cyberbemon

2

La herramienta fugas sólo le dirá dónde yo asignan los objetos que se piensa fugas Así, es decir. que, por ejemplo, que

NSString* answer = [NSString stringWithFormat: ... 

asigna un objeto que nunca se cancela la asignación. Ahora, -stringWithFormat: le da un objeto que you do not own y que no parece que retenerlo en cualquier lugar. por lo tanto, no es necesario para liberarlo , por lo que no puede estar goteando solo.

Eso significa que algo más do propio debe retenerlo y nunca lanzará esa otra cosa. El principal sospechoso parece ser stagePickerArray. Verifique que está liberando stagePickerArray en alguna parte. Si es local en -viewDidLoad, debe ser liberado o liberado automáticamente antes de que finalice ese método. Si se trata de una variable de instancia, se debe liberar en el método -dealloc de la clase.

+0

Gracias :) ¡Olvidé agregar el lanzamiento para la matriz! y esa fue la causa del problema! – cyberbemon