Pregunta

Similar al problema conocido de pérdida de memoria con respecto a la creación y destrucción de una instancia de UIImagePickerController, estoy encontrando problemas similares con respecto a las instancias de la clase UIViewController. La forma recomendada de usar UIImagePickerController es crear la instancia una vez y mantenerla durante toda la vida de la aplicación, aunque esto usará la memoria que puede necesitar en otro lugar.

La situación con la que estoy lidiando involucra 2 instancias de la clase UIViewController. Al inicio, se crea la primera instancia y su vista se agrega a otra " main " Clase UIViewController que forma parte de MainWindow.xib. En esta primera instancia hay un " información " botón que cuando se toca, cambia a una nueva instancia de la clase UIViewController (si aún no se ha creado). El " principal " UIViewController gestiona este cambio con la animación habitual de flip. La configuración básica se puede ver en la sección " Desarrollo inicial del iPhone: Explorando el iPhone SDK " libro de Dave Mark.

El problema que surge es que una vez que " información " el botón se toca la primera vez, la memoria se asigna a la nueva segunda instancia de UIViewController y no se libera hasta que la aplicación finalice. Debido a la cantidad de elementos en esta vista de información, utiliza aproximadamente 1 MB de memoria una vez que se crea una instancia y su vista se agrega a la vista de supervisión. Cualquier intento de destruir y recrear de forma consistente esta instancia produce una pérdida de memoria, similar a la que existe si intenta hacer lo mismo con las instancias de la clase UIImagePickerController. Sospecho que la causa raíz es la misma entre las dos clases.

El quid de mi problema es que necesito tener tanta memoria libre antes de permitir que el usuario tome una foto con la cámara. Sin embargo, una vez que el usuario ha tomado una foto y ve la imagen resultante la primera vez, se le permite tocar en " información " Botón que existe en la primera instancia de UIViewController. Una vez pulsado, el " principal " UIViewController elimina la vista de UIViewController existente y la reemplaza por la de la pantalla de información. La pantalla de información tiene un " atrás " Botón para cambiar las vistas de nuevo. Sin embargo, una vez que el usuario abandona la pantalla de información y elige tomar otra foto con la cámara, la memoria asignada a la pantalla de información aún está en la memoria.

La clase UIImagePickerController usa temporalmente casi 15-18MB mientras procesa la imagen de 2 megapíxeles antes de liberar sus referencias internas y el " imagePickerController: didFinishPickingImage " Se llama delegado. Me encuentro con alertas de poca memoria una vez que la segunda instancia de UIViewController se ha creado a través del botón de información y luego el usuario elige tomar otra foto.

Técnicamente, la memoria no tiene pérdidas si toma fotos una y otra vez con o sin tocar el botón de información en mi caso, pero debido a otros problemas relacionados con los procesos en segundo plano en el iPhone (Safari, etc.) que están fuera de su control, DEBE liberar tanta memoria como sea posible mientras trabaja con cosas como la cámara.

¿Algún consejo sobre cómo crear y destruir de manera limpia instancias de la clase UIViewController para que la memoria no se escape?

¿Fue útil?

Solución

¿Está cargando el segundo controlador de vista desde un NIB? Si es así, querrá comprobar que está liberando correctamente la memoria asociada.

Así es como se ve un controlador de vista típico basado en NIB en mis proyectos.

SomeViewController.h

@interface SomeViewController : UIViewController {
    UILabel *someLabel;
}

@property (nonatomic, retain) IBOutlet UILabel *someLabel;

@end

SomeViewController.m

@implementation SomeViewController

@synthesize someLabel;

- (void)dealloc {
    // Release our retained IBOutlets
    self.someLabel = nil;
    [super dealloc];
}

@end

Otros consejos

Una forma de reducir el uso de la memoria sería cambiar el tamaño de la imagen al tamaño que desee (a menos que, por supuesto, desee una imagen de 320x480). Eso ayudó mucho en mi caso.

¿Cambia el segundo controlador de vista del que está hablando? Si no es así, sería mejor convertirlo en un singleton y utilizar la misma instancia. Puede cambiar en cualquier momento los valores utilizados por el controlador de vista. Este artículo explica cómo puede crear objetos singleton ( con el código)

Otro artículo aquí muestra el uso de una clase de singleton (aunque diferente de su caso de uso, le aclarará cómo usar singletons)

También sugeriría crear un objeto singleton para UIImagePickerController.

¿Tiene algún ciclo en su cadena de propiedad? Algo como:

@interface FirstViewController: UIViewController {
  SecondViewController *secondViewController;
}
@end

@interface SecondViewController: UIViewController {
  FirstViewController *firstViewController;
}
@end

Si no rompes este ciclo explícitamente cuando descartas estos controladores de vista, se perderán.

Además, creo que eres responsable de liberar todos los objetos de nivel superior que se cargan desde un archivo de plumín cuando ya no los necesitas.

Tal vez podría guardar la imagen antes de pasar a la vista de información. Después de guardar, suelte la imagen y luego pase a la vista de información. Si el usuario vuelve, carga la imagen de la carpeta.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top