Cykl życia UIViewController obejmuje kluczowe metody:
init(nibName:bundle:) / init(coder:): inicjalizacjaloadView: tworzenie hierarchii widokówviewDidLoad: widok został załadowany (idealne miejsce do wstępnej konfiguracji)viewWillAppear / viewDidAppear: widok pokazuje/jest pokazanyviewWillDisappear / viewDidDisappear: widok znika/jest schowanydeinit: usunięcie kontroleraKolejność wywołania metod:
loadView, a następnie viewDidLoad)viewWillAppear/viewWillDisappear, następnie viewDidAppear/viewDidDisappeardeinitSzczegóły:
viewDidLoad nie należy odnosić się do rozmiarów widoków — mogą być one nieaktualnedeinit lub viewWillDisappearviewDidLoad, ale nie w viewWillAppear — w przeciwnym razie może dojść do duplikacji przy każdym pojawieniu sięPrzykład:
class MyViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() setupViews() setupBindings() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // Subskrybuj powiadomienia } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) // Wypisz się z powiadomień } deinit { // Oczyszczenie } }
Pytanie:
Czy widok kontroler może odnosić się do właściwości widoku poza cyklem życia (np. w inicjatorze)?
Odpowiedź:
Nie, przed wywołaniem (lub nadpisaniem) loadView wszystkie właściwości związane z widokiem mogą być nieinicjalizowane. Jakikolwiek dostęp do nich poza loadView/viewDidLoad spowoduje awarię.
Przykład:
// Błąd: self.view jeszcze nie zainicjalizowane! init() { super.init(nibName: nil, bundle: nil) self.view.backgroundColor = .red //AWARIA }
Historia
Projekt się zawieszał z powodu przedwczesnego odwoływania się do self.view w init — widok nie został stworzony, co prowadziło do awarii.
Historia
W dużych projektach zapominali o wypisaniu się z NotificationCenter lub delegate w viewWillDisappear i/lub deinit, co prowadziło do wycieków pamięci (NotificationCenter odnosił się do view controller, ten nie był usuwany i nadal słuchał zdarzeń).
Historia
W viewWillAppear przy każdym pojawieniu się dodawano nowe subwidoki do widoku (na przykład, pokazywano wskaźnik ładowania), nie sprawdzając istnienia. W rezultacie przy każdym powrocie na ekran pojawiało się coraz więcej duplikujących się wskaźników, UI przestawał działać.