El ciclo de vida de UIViewController incluye métodos clave:
init(nibName:bundle:) / init(coder:): inicializaciónloadView: creación de la jerarquía de vistasviewDidLoad: vista cargada (lugar ideal para configuraciones iniciales)viewWillAppear / viewDidAppear: vista se muestra/se ha mostradoviewWillDisappear / viewDidDisappear: vista está a punto de ocultarse/ha sido ocultadadeinit: eliminación del controladorOrden de llamados a los métodos:
loadView, luego viewDidLoad)viewWillAppear/viewWillDisappear, luego viewDidAppear/viewDidDisappeardeinitMatices:
viewDidLoad no se deben consultar los tamaños de la vista, ya que pueden no estar actualizadosdeinit o viewWillDisappearviewDidLoad, pero no en viewWillAppear — de lo contrario, puede haber duplicación con cada apariciónEjemplo:
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:
¿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 }
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.