Las imágenes de la vista de tabla nunca se publicaron

Estoy trabajando en una actualización importante de una de mis aplicaciones y estoy tratando de reducir el uso de memoria y hacerlo más limpio y más rápido. Estaba usando Instruments para perfilar la aplicación y estaba mirando las asignaciones de UIImage, tengo alrededor de 10 cuando la aplicación comienza (aunque uno es un ícono de la barra de estado? No sé por qué está incluido). Cuando abro mi controlador de vista de Configuraciones (que está en un controlador de vista dividida en iPad) tiene básicamente una imagen con cada celda de vista de tabla, que es mucho. Presentarlo por primera vez agrega 42 imágenes. cuando descarto este controlador de vista, todavía hay 52 imágenes, cuando debería haber solo 10 ahora. Si vuelvo a presentar el controlador, ahora hay 91 imágenes. Esto sigue subiendo y subiendo. Instruments no dice que hay una fuga y no puedo entender lo que está sucediendo. Cada celda establece una imagen como

cell.imageView.image = [UIImage imageNamed:@"Help-Icon"]; 

¿Cómo puedo descubrir por qué estas imágenes no se están lanzando?

enter image description here

EDITAR: Creo que está desasignando las imágenes ahora. Cambié la configuración de la imagen de imageView directamente a setImage: así que una celda de la tabla se ve así ahora:

  cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier]; } cell.textLabel.text = NSLocalizedString(@"Homepage", @"Homepage"); UIImage *cellImage = [UIImage imageNamed:@"Homepage-Icon"]; [cell.imageView setImage:cellImage]; [MLThemeManager customizeTableViewCell:cell]; return cell; 

MLThemeManager es un singleton que usa una clase de tema para establecer las propiedades de la celda en un tema, como el color de la etiqueta de texto, el color resaltado, el color de la etiqueta de texto detallado y el color de fondo.

La posible razón aquí es debido a que su controlador de vista de Configuración no fue desasignado (no liberado de la memoria). No importa cuántas imágenes haya en ese controlador de vista cuando el controlador de vista se libera de la memoria, desasignará (eliminará) todos los objetos de imagen de la memoria.

¿Cómo comprobar que su controlador de vista está asignado (versión) o no?

Pasos:

  1. Desde Xcode, mantén presionado el botón Ejecutar. Obtienes una pequeña ventana emergente, selecciona Perfil de eso. Y puedes ver que el ícono nuevo reemplaza al ícono Ejecutar . (De manera similar, puede cambiarlo para ejecutar la aplicación).

enter image description here

  1. Haga clic en este botón para comenzar a perfilar su aplicación.

  2. Seleccione la sección Asignaciones en la ventana Instrumentos . Hay un campo de texto sobre la vista de listado de asignaciones. Haga clic en ese campo y escriba su nombre de controlador de vista. (En su caso SettingViewController).

enter image description here

  1. Solo puede ver el resultado del filtro relacionado con esa palabra clave que acaba de escribir. Ahora ve a Simulator -> Simula tu flujo. Retroceda desde su controlador de vista y compruebe en Instrumentos que después de salir de ese controlador de vista si todavía está en la lista. Si está allí en una lista, su controlador de vista no se libera de la memoria y cada vez que abra esa vista, el controlador boostá la memoria y nunca se liberará hasta que se ejecute la aplicación.

¿Cómo podemos asignar el controlador de vista?

Trataré de explicar de alguna manera que conozco el controlador asignado.

[1] Anula el método dealloc en tu controlador de vista y suelta objetos en eso. Variable principalmente mutable y delegates. Coloque un punto de interrupción de depuración en el método de -dealloc y asegúrese de que se -dealloc cuando dejó el controlador.

Nota: Si tiene una variable global para clases como UIPickerView , UIPickerView , UIPopoverController , etc. y configure delegates para eso, estos delegates deben ser nil en el método de -dealloc .

p.ej

Código objective C:

 //--------------------------------------------------------------- #pragma mark #pragma mark Memory management methods //--------------------------------------------------------------- - (void) dealloc { [self.tableView setDelegate:nil]; [self.tableView setDataSource:nil]; } 

Código SWIFT:

 deinit { self.tableView.dataSource = nil self.tableView.delegate = nil } 

[2] El objeto global de la subclase también debe sobrescribir el método de -dealloc y liberar objetos y delegates relevantes. Similar debe ser llamado su método dealloc.

p.ej

Verifique este escenario: supongamos que ha creado una subclase de UIView (o cualquier otra vista) con el nombre MenuView . Y ha creado una variable global de esta clase en su controlador de vista, que se dealloc método dealloc antes del método dealloc del controlador de dealloc .

 @property (nonatomic, strong) MenuView *menuView; 

Por lo tanto, aquí la clase MenuView debe sobrescribirse en el método -dealloc y debe -dealloc antes de dealloc método dealloc su controlador de vista.

De modo que, antes de abandonar el contenedor completo, sus vistas secundarias se liberen y se eliminen de la memoria.

Compruebe esto en Instrumentos para la clase MenuView también ese objeto sigue siendo su o no?

Si no se llama al método dealloc, el objeto de la clase MenuView aún está en la memoria y su clase de controlador de vista hace referencia a ese objeto. Así que incluso si se llama al -dealloc su controlador de vista, no se desasignará porque el objeto de la clase MenuView está MenuView .


[3] IBOutlet establecer weak referencia weak para IBOutlet . p.ej

Código objective C:

 @property (nonatomic, weak) IBOutlet UITableView *tableView; 

Código SWIFT:

 @IBOutlet weak var tableView: UITableView! 

No dude en preguntar si algo no está claro.

No use el elemento de imagen … Copie las imágenes en una carpeta en su proyecto y cárguelas por código con imageWithContentOfFile para mí.

Intenta usar imageWithContentsOfFile para cargar la imagen.

Como dijo rmaddy, imageNamed permitirá que su imagen permanezca en el caché, esta es la razón de su problema de memoria