ProgramaciónDesarrollador iOS

Describe el ciclo de vida del view controller en UIKit y cómo un manejo incorrecto de este ciclo puede llevar a fugas de memoria o errores en la interfaz de usuario. ¿Qué matices se deben conocer?

Supere entrevistas con el asistente de IA Hintsage

Respuesta

El ciclo de vida de UIViewController incluye métodos clave:

  • init(nibName:bundle:) / init(coder:): inicialización
  • loadView: creación de la jerarquía de vistas
  • viewDidLoad: vista cargada (lugar ideal para configuraciones iniciales)
  • viewWillAppear / viewDidAppear: vista se muestra/se ha mostrado
  • viewWillDisappear / viewDidDisappear: vista está a punto de ocultarse/ha sido ocultada
  • deinit: eliminación del controlador

Orden de llamados a los métodos:

  • Primero se crea la jerarquía de vistas (loadView, luego viewDidLoad)
  • En cada aparición y ocultación en pantalla se llaman viewWillAppear/viewWillDisappear, luego viewDidAppear/viewDidDisappear
  • Después de la eliminación — deinit

Matices:

  • En viewDidLoad no se deben consultar los tamaños de la vista, ya que pueden no estar actualizados
  • Es importante liberar recursos (observadores, temporizadores) en deinit o viewWillDisappear
  • Añadir subviews — en viewDidLoad, pero no en viewWillAppear — de lo contrario, puede haber duplicación con cada aparición

Ejemplo:

class MyViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() setupViews() setupBindings() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // Suscribirse a notificaciones } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) // Cancelar suscripción a notificaciones } deinit { // Limpiar } }

Pregunta trampa

Pregunta:

¿Es permitido que el view controller acceda a las propiedades de la vista fuera del ciclo de vida (por ejemplo, en el inicializador)?

Respuesta: No, hasta que se llame (o se sobreescriba) loadView, todas las propiedades relacionadas con la vista pueden no estar inicializadas. Cualquier acceso a ellas fuera de loadView/viewDidLoad provocará un crash.

Ejemplo:

// Error: self.view aún no está inicializada! init() { super.init(nibName: nil, bundle: nil) self.view.backgroundColor = .red //CRASH }

Ejemplos de errores reales debido al desconocimiento de los matices del tema


Historia

El proyecto fallaba debido a un acceso prematuro a self.view en init — la vista no había sido creada, lo que llevaba a un crash.


Historia

En grandes proyectos se olvidaban de cancelar la suscripción a NotificationCenter o delegados en viewWillDisappear y/o deinit, lo que llevaba a fugas de memoria (NotificationCenter seguía apuntando al view controller, que no se liberaba y seguía escuchando eventos).


Historia

En viewWillAppear, cada aparición se añadían nuevas subviews a la vista (por ejemplo, un indicador de carga), sin verificar su existencia. Como resultado, con cada regreso a la pantalla, aparecían cada vez más indicadores duplicados, y la UI fallaba.