2010-03-04 19 views
7

Uso instrumentos para ver pérdidas de memoria. Al menos en un escenario en el que estoy constantemente hojeando diapositivas/páginas (dentro de UIScrollView) no veo ninguna pérdida de memoria. Uso de instrumentos: bajo "Duración de la asignación", cambio para ver "Creado & Aún vivo" y veo una memoria de alrededor de 1,17 MB en todo. Supongo que esto significa que mi aplicación está utilizando solo esta cantidad de memoria y el resto se recicla correctamente.Advertencia de memoria y bloqueo: cómo manejarlo

Sin embargo, después de hojear unas 100 páginas, recibo una advertencia de memoria y luego algunas de mis vistas se descargan, lo que da como resultado un bloqueo de toda la aplicación.

Si no estoy usando mucha memoria y no tengo pérdida de memoria, ¿por qué recibí una advertencia de memoria? Como no hay nada que realmente pueda liberar, no veo una manera de evitar el colapso. ¿Alguien experimentó esta situación o sabe qué puedo hacer? ¿Estoy malinterpretando algo de los instrumentos? Muchas gracias por cualquier comentario.

+0

ninguna pista todavía. Tal vez 'Instruments' no está informando adecuadamente sobre alguna filtración que pueda tener. ¿Hay otras herramientas para encontrar fugas de memoria que sean más confiables? – climbon

Respuesta

11

The documentation says:

Si un objeto de imagen juego no está ya en la memoria caché, este método carga los datos de la imagen desde el archivo especificado, lo almacena en caché, y luego devuelve el objeto resultante.

Por lo tanto, cada imagen que cargue usando imageNamed: seguirá existiendo en la memoria caché después de que libere su última propiedad de la misma.

Los instrumentos no muestran esto como una fuga porque, estrictamente hablando, no es uno: Algo (UIImage) todavía sabe acerca de estas imágenes. El instrumento Leaks solo mostrará una fuga de un objeto que existe, pero no se sabe nada.

Aún así puedes ver esto en Instrumentos.

  1. Seleccione el instrumento ObjectAlloc en su documento de seguimiento y ordene la lista de clases por recuento actual o por tamaño total actual. Verás que la mayor parte de la memoria está ocupada por objetos UIImage.
  2. Si pasa el mouse sobre la columna de nombre de clase para la fila UIImage, verá un ícono ➲ (ir a iTunes Store); si haces clic en eso, verás una lista de todas tus instancias de UIImage.
  3. Luego, si pasa el mouse sobre la columna de la dirección para la fila de una instancia, verá el mismo botón; esta vez, al hacer clic en él, accederá al historial de esa dirección, incluidas todas las creaciones, retenciones, versiones y desasignaciones de objetos con esa dirección.

    Aquí puede ver la asignación de la imagen (dentro de la clase UIImage, ordenada por usted unos cuantos stack-frames abajo), retención (por usted) y release (por usted). También puede ver que no ha sido liberado por UIImage: la memoria caché +[UIImage imageNamed:] aún es propietaria de la imagen, de ahí la "fuga".

Si no desea que las imágenes se acumulan así, cargarlos por sí mismo utilizando imageWithContentsOfFile: y the -[NSBundle pathForResource:ofType:] method.

ACTUALIZACIÓN: He leído que desde iOS 3, UIImage purgará su caché en (al menos algunos) situaciones de poca memoria, por lo que esto no debería ser tanto de una “fuga”, como lo que solía ser. Probablemente aún verás la acumulación de memoria, pero luego verás que el montón se colapsa eventualmente. Si todavía ve acumularse la memoria y puede demostrar que es culpa de Apple, debe documentar su evidencia y file a bug.

+0

¡Un millón de veces GRACIAS! – RanLearns

0

Encontrado el origen del problema. Es en el siguiente fragmento de

UIImage *image = [UIImage imageNamed:imageFile]; 

cartoon = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 40.0, 320, 280)]; 

cartoon.image = image ; 
cartoon.backgroundColor = [UIColor brownColor]; 

tengo 100s de imágenes, además de un poco de texto en cada página y el usuario puede desplazarse a través de ellos por el dedo parpadeo (al igual que lo hacen en la aplicación de fotos del iPhone). Solo creo 3 páginas en mi UIScrollView y cargo/descargo (y también lanzo) todo lo que asigné explícitamente. Entonces, cuando se trata de lanzar la caricatura, simplemente lanzo la caricatura UIImageView y no el UIImage pensando que será lanzado automáticamente.

Pero parece que no se está lanzando automáticamente. Mi aplicación recibe una advertencia de memoria (no realizo ninguna acción) y el SO descarga mis vistas, lo que provoca el bloqueo.

Cuando comente las dos líneas (fragmento modificado a continuación), el problema desaparece. No hay advertencia, no se cuelga.

//UIImage *image = [UIImage imageNamed:imageFile]; 

cartoon = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 40.0, 320, 280)]; 

//cartoon.image = image ; 
cartoon.backgroundColor = [UIColor brownColor]; 

¿Alguien sabe cómo solucionar este problema? ¿Hay alguna manera de forzar la memoria de liberación de UIImage cuando ocurre una advertencia?

+0

Está siendo lanzado automáticamente. También es propiedad de otra cosa. Puedes ver esto mirando instancias de UIImage individuales en Instruments. –

2

¿Tiene la variable de entorno NSZombieEnabled establecida en sí? Causará que los objetos desasignados persistan en la memoria, lo que no le permitirá recuperar la memoria. Intente deshabilitarlo, si está activo.

1

¿Ha comprobado que libera todos sus objetos IBOutlet? En su dealloc debe liberar cualquier objeto IBOutlet que tenga en su objeto, incluso si no tienen un método de sintetización.

Tenemos un problema similar y lo hemos resuelto liberando todos los IBOutlets.

Check this answer in Stack Overflow

1

Si sólo tiene 3 páginas entiendo que va a reutilizar algunos elementos.

Sin el resto del código, es difícil decir qué está yendo mal, pero tal vez deberías intentar liberar el objeto de dibujos animados antes de crear uno nuevo.

intentar algo como esto:

IImage *image = [UIImage imageNamed:imageFile]; 

if (cartoon!=nil) 
    [cartoon release]; 

cartoon = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 40.0, 320, 280)]; 

cartoon.image = image ; 
cartoon.backgroundColor = [UIColor brownColor]; 
Cuestiones relacionadas