ViewController Lifecycle — är en sekvens av metoder som UIKit automatiskt anropar vid hantering av skärmar i iOS. Enligt Apple Documentation går varje UIViewController igenom en förutsägbar uppsättning tillstånd: från att View skapas till att den visas och döljs. Att förstå ordningen och syftet med dessa metoder är en nödvändig förutsättning för stabil drift av iOS-applikationen.
Huvudpunkter
ViewController Lifecycle — är en uppsättning metoder som UIViewController får från UIKit under sin existens. Varje skärm i en iOS-applikation går successivt igenom faserna skapande, laddning av View, visning på skärmen, försvinnande och frigöring av minne. UIKit anropar automatiskt motsvarande metoder i varje fas och utvecklaren överskriver dem och lägger till sin egen logik.
Arkitekturen för UIViewController är grunden i UIKit och förblir relevant även i SwiftUI-eran — många projekt använder fortfarande den klassiska metoden eller hybridarkitektur. Att förstå Lifecycle gör det möjligt att förutsäga när subviews är tillgängliga, när layouten säkert kan ändras och vilka operationer som ska utföras när skärmen visas eller döljs.
Varje metod i livscykeln har ett specifikt syfte: vissa anropas en gång under kontrollantens hela existens, andra — vid varje visning eller försvinnande. Att blanda logik mellan metoder leder till svårupptäckta buggar: minnesläckor, felaktiga datauppdateringar och onödiga nätverksförfrågningar.
Sex metoder utgör den fullständiga livscykeln för UIViewController. Ordningen för deras anrop är fast och beror inte på navigeringssättet — push, present eller unwind segue följer samma schema.
loadView — den första metoden i cykeln, anropas när kontrollantens View ännu inte finns. Om du använder Storyboard laddar UIKit automatiskt View från xib-filen. Vid programmatiskt skapande av gränssnittet överskriver du denna metod och tilldelar rot-View manuellt. I de flesta projekt rörs inte loadView — arbetet görs i viewDidLoad.
Att överskriva loadView krävs endast i specifika fall: när hela gränssnittet skapas med kod utan Storyboard eller när rot-View måste vara av en icke-standardklass. Apple rekommenderar att inte anropa super.loadView vid överskrivning — du tar helt över skapandet av View.
override func loadView() {
view = UIView()
view.backgroundColor = .white
}
viewDidLoad — den mest använda metoden i cykeln. Den anropas en gång efter att View har laddats i minnet men innan den visas på skärmen. Här konfigureras subviews, tabeller fylls med data, celler registreras och prenumerationer på notifikationer som gäller under hela kontrollantens livstid görs.
Viktig egenskap: viewDidLoad anropas inte igen när skärmen visas igen. Om du behöver uppdatera data varje gång skärmen visas — använd viewWillAppear. I viewDidLoad placerar du endast engångsoperationer som baskonfigurationen beror på.
viewWillAppear anropas varje gång omedelbart innan View blir synlig för användaren. Denna metod tar emot parametern animated, som anger om visningen sker med animation. Här uppdateras data, tabeller laddas om, NavigationBar konfigureras och element döljs eller visas beroende på applikationens tillstånd.
Använd viewWillAppear för synkronisering av tillstånd mellan skärmar: om användaren kan ha ändrat data på föregående skärm är denna metod rätt plats att uppdatera gränssnittet. Varje anrop av viewWillAppear föregår skärmens visning, även vid återkomst från en underordnad kontrollant.
viewDidAppear meddelar att View har visats helt på skärmen och alla övergångsanimationer har slutförts. I detta ögonblick är skärmen redo för interaktion — användaren ser hela gränssnittet och kan arbeta med det. Denna metod är lämplig för att starta animationer som ska börja efter visning, starta timers och spåra analysvisningar.
Till skillnad från viewWillAppear garanterar viewDidAppear att skärmen inte bara är synlig utan helt renderad. Om du startar en animation i viewWillAppear kan vissa bildrutor hoppas över eftersom UIKit inte har slutfört övergången ännu. För jämna animationer, använd viewDidAppear.
viewWillDisappear anropas innan View försvinner från skärmen — vid övergång till en annan kontrollant, stängning av ett modalt fönster eller minimering av applikationen. Detta är rätt plats att spara tillstånd, avsluta prenumerationer på notifikationer, stoppa aktiva processer och frigöra resurser som inte behövs när skärmen inte är synlig.
Viktigt att komma ihåg: viewWillDisappear garanterar inte att View slutligen försvinner — gesten kan avbrytas. Därför sparar du kritiska data även i viewDidDisappear, som anropas först efter faktiskt försvinnande.
viewDidDisappear avslutar cykeln av visning och försvinnande. Det anropas efter att View redan har dolts från skärmen. I denna metod stoppas animationer definitivt, temporära objekt tas bort och datalagring som påbörjats i viewWillDisappear bekräftas.
Denna metod föregår också kontrollantens deinit — om din UIViewController förstörs kommer viewDidDisappear att vara den sista Lifecycle-metoden före anropet av deinit. Använd den för slutlig rensning som måste ske innan objektet förstörs.
Ordningen för anrop beror på hur skärmen visas: första gången, vid återkomst eller vid modal visning. Låt oss titta på tre huvudsakliga scenarier ur UIKit perspektiv.
Vid skärmens första visning går UIKit igenom den fullständiga skapelsecykeln: loadView anropas, sedan viewDidLoad, därefter börjar visningsanimationen. Under animationen anropas viewWillAppear och efter slutförande — viewDidAppear. Detta är det enda scenariot där alla metoder från loadView till viewDidAppear anropas i följd.
override func viewDidLoad() {
super.viewDidLoad()
print("viewDidLoad — View laddad i minnet")
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
print("viewWillAppear — kommer snart att visas")
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print("viewDidAppear — skärm helt synlig")
}
När användaren återvänder till föregående skärm anropar UIKit inte viewDidLoad igen — View är redan laddad i minnet. Istället utlöses på den återvändande skärmen endast viewWillAppear och viewDidAppear och på den aktuella — viewWillDisappear och viewDidDisappear. loadView och viewDidLoad hoppas över eftersom skärmen redan finns i navigeringsstacken.
Modal visning följer samma regler: hos den nya kontrollanten anropas hela cykeln vid första visningen och hos den aktuella — viewWillDisappear och viewDidDisappear. Vid är ordningen omvänd: hos den återvändande kontrollanten utlöses viewWillAppear och viewDidAppear igen och hos den dolda — avslutande metoder. Detta beteende är enhetligt för alla övergångstyper i UIKit.
Låt oss titta på fyra nyckelscenarier där förståelse av Lifecycle direkt påverkar kodkvalitet och användarupplevelse. För varje scenario ger vi ett exempel med rekommendationer.
viewDidLoad — platsen för initial konfiguration som inte beror på skärmens synlighet. Här konfigureras collectionView, nib-filer för celler registreras, data source och layout skapas. Om du laddar data från nätet är det bättre att bara initiera förfrågan i viewDidLoad och uppdatera gränssnittet i viewWillAppear när skärmen är redo att visas.
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(
MyCell.self,
forCellReuseIdentifier: MyCell.identifier
)
viewModel.loadInitialData()
}
Använd viewWillAppear för att synkronisera data varje gång skärmen visas. Om användaren till exempel kan ha ändrat inställningar på föregående skärm uppdateras här de visade värdena, tabellen laddas om och NavigationBar-tillståndet korrigeras. Detta garanterar att skärmen alltid visar aktuell data vid alla navigeringsscenarier.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tableView.reloadData()
navigationController?.setNavigationBarHidden(false, animated: animated)
}
viewDidAppear är idealiskt för att starta animationer som ska börja efter att användaren har sett skärmen. Här skickas även analyshändelser: skärmvisning, start av onboarding eller start av videouppspelning. Att starta animationer innan övergången är slutförd leder till ett hackigt gränssnitt — UIKit hinner inte förbereda tillräckligt många bildrutor.
I viewWillDisappear sparas utkast, timers stoppas och prenumerationer på NotificationCenter avslutas. Detta är det sista ögonblicket när skärmen är synlig och tillgänglig för operationer som kräver användarkontext. För kritisk data används även viewDidDisappear som försäkring mot avbrutna gester.
Felaktig användning av livscykelmetoder är en av de vanligaste källorna till buggar i iOS-applikationer. Låt oss titta på de huvudsakliga misstagen som utvecklare gör i olika faser av arbetet med UIViewController.
Första misstaget — att skapa subviews i init eller loadView när Storyboard används. Om du använder Interface Builder, överskrid inte loadView i onödan. Att skapa View i loadView med en befintlig storyboard leder till att xib-filen ignoreras och en tom skärm.
Andra misstaget — prenumeration på tangentbordsnotifikationer i viewDidLoad utan att avsluta prenumerationen. Om du prenumererat på UIResponder.keyboardWillShowNotification men inte avslutat prenumerationen när skärmen döljs kommer blocket att anropas även efter kontrollantens deinit — detta är en minnesläcka med potentiell krasch av applikationen.
Tredje misstaget — timers och nätverksförfrågningar som startats innan skärmen visas. Att ladda bilder eller utföra animationer när View ännu inte är synligt — slöseri med resurser. Flytta visuella uppdateringar till viewWillAppear eller viewDidAppear.
Fjärde misstaget — att spara data endast i viewWillDisappear. Vid interaktiv pop-gest kan användaren påbörja en svepning och avbryta den — metoden anropades men skärmen försvann inte. Duplicera kritisk lagring i viewDidDisappear eller i hanteraren för applicationDidEnterBackground.
Vanliga frågor
En gång — efter att View har laddats i minnet. Vid upprepade visningar av skärmen anropas inte viewDidLoad. Om View behöver återskapas måste kontrollanten förstöras och skapas på nytt.
UIKit kräver att super.viewDidLoad anropas för korrekt funktion av livscykeln. Utan det kan problem uppstå med layoutuppdatering och hantering av övergångar. Anropa alltid super som första sak i metoden.
Rekommenderas inte. Om kontrollanten initialiseras från Storyboard laddar UIKit automatiskt View från xib. Att överskriva loadView avbryter denna process och din storyboard kommer att ignoreras.
Prenumerera i viewDidLoad eller viewWillAppear och avsluta prenumerationen i viewWillDisappear eller viewDidDisappear, med en svag referens till self för att undvika minnesläckor i closures.
Force quit dödar processen tvångsmässigt — UIKit hinner inte anropa Lifecycle-metoder. För att spara data, använd notiseringen UIApplication.willTerminateNotification i AppDelegate.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också