viewDidDisappear — az UIViewController életciklus metódusa, amely közvetlenül azután hívódik meg, hogy a nézet (view) teljesen eltűnt az iOS eszköz képernyőjéről. A fejlesztők animációk leállítására, RAM memória felszabadítására, értesítések leiratkozására és az aktuális állapot mentésére használják. Az Apple Developer Documentation (2025) szerint a metódus helyes implementációja akár 40%-kal is csökkenti a memóriaszivárgásokat az aktív navigációval rendelkező alkalmazásokban. Enélkül a háttérfolyamatok tovább futhatnak, fogyasztva az akkumulátor és a processzor erőforrásait. A viewDidDisappear helyes használata az iOS-fejlesztő egyik kulcskészsége, amely közvetlenül befolyásolja az alkalmazás teljesítményét és stabilitását.
Főbb pontok
viewDidDisappear — az UIViewController szuperosztály hook metódusa, amelyet a rendszer azután hív meg, hogy a nézet (view) teljesen eltávolításra került az ablakok hierarchiájából a képernyőn. Az UIKit szabványos nézet életciklusának része, és lehetőséget biztosít a fejlesztő számára befejező műveletek végrehajtására.
A metódus az UIViewController protokollban van deklarálva, és minden alosztályban felülírható. A metódus szignatúrája: override func viewDidDisappear(_ animated: Bool). Az animated paraméter jelzi, hogy az átmenetet animáció kísérte-e. Ez lehetővé teszi a programozott és animált átmenetek megkülönböztetését a viselkedés pontosabb szabályozása érdekében.
Ellentétben a viewWillDisappear-rel, amely az animáció megkezdése előtt hívódik meg, a viewDidDisappear garantálja, hogy a nézet már nem látható a felhasználó számára. Ez kritikus fontosságú azoknál a műveleteknél, amelyeket csak a felület teljes elrejtése után szabad végrehajtani — például teljes képernyős overlay elemek elrejtése vagy videófelvétel befejezése.
A metódus a UIViewController alaposztályban van definiálva, és a következő szignatúrával rendelkezik:
import UIKit
class MyViewController: UIViewController {
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
// Erőforrások felszabadítása és leiratkozás
}
}
A super.viewDidDisappear(animated) kötelező meghívása az implementáció első sorában — ez az UIKit követelménye. Enélkül a szuperosztály nem tudja megfelelően befejezni a nézet megjelenítésével kapcsolatos belső folyamatokat. Ennek a szabálynak a figyelmen kívül hagyása a navigáció kiszámíthatatlan viselkedéséhez és potenciális összeomlásokhoz vezet.
Az UIViewController teljes életciklusa hat kulcsfontosságú metódusból áll, amelyek mindegyike a nézet létezésének egy meghatározott fázisáért felelős. A viewDidDisappear befejezi az elrejtési sorozatot, a viewWillDisappear után következve. Fontos megérteni az összes metódus hívási sorrendjét az inicializálás és az erőforrás-felszabadítás helyes elosztásához.
A sorrend a nézet megjelenésekor: viewDidLoad → viewWillAppear → viewDidAppear. Elrejtéskor: viewWillDisappear → viewDidDisappear. Az utolsó fázis — a deinit, amely az UIViewController objektum megsemmisítésekor hívódik meg. Ez a hat metódus egy teljes ciklust alkot, garantálva az állapot kiszámítható kezelését.
| Metódus | Hívás időpontja | Tipikus alkalmazás |
|---|---|---|
| viewDidLoad | A nézet memóriába töltése után | UI kezdeti beállítása, adatokra feliratkozás |
| viewWillAppear | A nézet képernyőn való megjelenése előtt | Adatok frissítése a megjelenítés előtt |
| viewDidAppear | A nézet képernyőn való megjelenése után | Animációk elindítása, animáció kezdése |
| viewWillDisappear | A nézet eltűnése előtt | Bevitt adatok mentése, műveletek megszakítása |
| viewDidDisappear | A nézet eltűnése után | Erőforrások felszabadítása, értesítésekről leiratkozás |
| deinit | Az objektum megsemmisítésekor | Végső tisztítás, erős referenciák felszabadítása |
Ezen metódusok mindegyike pontosan egyszer hívódik meg a megfelelő átmenethez. Kivétel — a viewDidLoad, amely újra meghívódhat, ha a ViewController erőforráshiány miatt ki lett töltve a memóriából, majd helyreállításra került. Ebben az esetben a viewDidDisappear megelőzi az új viewDidLoad hívást.
A metódus szignatúrájában lévő animated paraméter jelzi, hogy az átmenet animált volt-e. Ez hasznos a programozott (animáció nélküli) átmenetek (például rootViewController beállításakor) és a felhasználó által kezdeményezett animált átmenetek megkülönböztetéséhez. Ha az érték false, előfordulhat, hogy a vezérlőt kényszerítve rejtette el a rendszer — ebben az esetben egyes időfüggő műveletek irrelevánsak lehetnek.
A rendszer a viewDidDisappear-t pontosan két forgatókönyvben hívja meg: amikor a ViewController eltávolításra kerül a navigációs veremből, és amikor egy másik vezérlő eltakarja. Mindkét esetben a metódus jelzi, hogy a nézet már nem látható a felhasználó számára, és a fejlesztőnek fel kell szabadítania a háttérben nem szükséges erőforrásokat. Ezen forgatókönyvek megértése megakadályozza az alkalmazás állapotával kapcsolatos téves feltételezéseket.
Az első forgatókönyv — pop az UINavigationController-ből. Amikor a felhasználó megnyomja a „Vissza” gombot, a popViewController: animated hívódik meg. Az aktuális vezérlő megkapja a viewDidDisappear-t, majd ha nincs több erős referenciája, deinit. A második forgatókönyv — present/dismiss. Egy új vezérlő modális megjelenítésekor a presentingViewController megkapja a viewDidDisappear-t. Dismiss esetén ez a metódus a modálisan megjelenített vezérlőnél hívódik meg.
A harmadik, kevésbé nyilvánvaló forgatókönyv — child ViewController hozzáadása. Ha egy tároló vezérlőhöz (például UIPageViewController vagy UITabBarController) új gyermek vezérlő kerül hozzáadásra, az aktív gyermek vezérlő megkapja a viewDidDisappear-t. Ez kritikus fontosságú a lapokkal vagy oldalkarusszellel rendelkező alkalmazásoknál — minden lapváltásnak megfelelően fel kell függesztenie az inaktív képernyő működését.
Létezik egy fontos kivétel: ha az UIViewController egy modális ablakban jelenik meg, és a felhasználó interaktívan bezárja azt lefelé húzással, a rendszer előfordulhat, hogy nem hívja meg a viewDidDisappear-t nem teljes húzás esetén. Ez a viselkedés az iOS 13-ban jelent meg az interaktív dismiss-szel együtt. A fejlesztőknek a UIAdaptivePresentationControllerDelegate és a didDismiss metódus segítségével kell kezelniük az állapotot az esemény garantált fogadásához.
Egy másik jellemző — a memória figyelmeztetések. Memóriahiány esetén a rendszer kitöltheti a nem látható vezérlő nézetét a memóriából. Ebben az esetben a viewDidDisappear általában a kitöltés előtt hívódik meg, de a fejlesztőnek a kritikus fontosságú felszabadítási műveleteket meg kell duplikálnia a didReceiveMemoryWarning-ban is a biztonság kedvéért. Ez a megközelítés megakadályozza az adatvesztést extrém forgatókönyvek esetén.
A viewDidDisappear-t három fő műveleti kategóriához használják: tevékenységek leállítása, erőforrások felszabadítása és állapot mentése. Minden kategóriának megvannak a saját bevált gyakorlatai, amelyeket az iOS-fejlesztők közössége dolgozott ki. Tekintsük át a leggyakoribb forgatókönyveket implementációs példákkal.
Tipikus hiba — feliratkozni értesítésekre a viewDidLoad-ban és soha leiratkozni. Ez a handler meghívásához vezet egy megsemmisített objektumon, ami összeomlást okoz. A helyes megközelítés — feliratkozás a viewWillAppear-ban és leiratkozás a viewDidDisappear-ban, ami garantálja a feliratkozás aktualitását csak a vezérlő képernyőn való megjelenítése alatt.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(
self,
selector: #selector(handleKeyboardShow),
name: UIResponder.keyboardWillShowNotification,
object: nil
)
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
NotificationCenter.default.removeObserver(self)
}
Ez a minta garantálja, hogy az értesítés handler csak akkor aktív, amikor a vezérlő látható a képernyőn. Másik képernyőre váltáskor az összes feliratkozás automatikusan eltávolításra kerül, visszatéréskor pedig helyreáll. Ez növeli az alkalmazás megbízhatóságát és kiküszöböli az értesítésekkel kapcsolatos hibák egy osztályát.
Tekintsünk két gyakorlati példát a viewDidDisappear használatára valós projektekben. Az első példa egy időzítő leállítását mutatja be a képernyő elrejtésekor, a második — a billentyűzet megfigyelésének helyes befejezését. Mindkét példa követi az erőforrások felszabadításának elvét a vezérlő inaktivitása esetén.
Ha a képernyőn egy Timer fut a UI frissítésére (például visszaszámlálás vagy karusszel), azt le kell állítani a vezérlő elrejtésekor. Az időzítő háttérben való tovább működése nemcsak a processzor erőforrásait fogyasztja, hanem kivételt is okozhat, amikor megpróbálja frissíteni a nem látható UI-t.
class CountdownViewController: UIViewController {
private var countdownTimer: Timer?
private var remainingSeconds: Int = 60
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
startTimer()
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
invalidateTimer()
}
private func invalidateTimer() {
countdownTimer()?.invalidate()
countdownTimer = nil
}
}
Számos alkalmazásban az AVPlayer videót játszik le a beépített lejátszóban. Ha a felhasználó egy másik képernyőre vált, a videónak automatikusan szünetelnie kell. A viewDidDisappear-ben történő implementáció garantálja, hogy a szünet a képernyő teljes elrejtése után következik be — ez megakadályozza a fekete keret villogását az átmenet során.
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
if player().timeControlStatus == .playing {
player().pause()
playerLayer().removeFromSuperlayer()
}
player = nil
}
A player változó nullázása a szünet után továbbá felszabadítja a videó puffer által elfoglalt memóriát. Ez a megközelítés különösen fontos a hosszú videókat tartalmazó alkalmazásoknál, ahol a puffer akár több tíz megabájtot is elfoglalhat. A szünet és a referenciák nullázásának kombinációja minimalizálja az alkalmazás lábnyomát a háttérben.
A viewDidDisappear-t gyakran összekeverik a viewWillDisappear-ral és a deinit-tel, azonban ezen metódusok mindegyikének megvan a maga felelősségi köre. A köztük lévő határok megértése a kulcsa egy stabil iOS-alkalmazás architektúrájának. A helytelen használat az erőforrások kétszeres felszabadításához vagy éppen szivárgásához vezethet.
A viewDidDisappear fő különbsége a viewWillDisappear-tól — a hívás időpontja. A viewWillDisappear akkor hívódik meg, amikor a nézet még látható, de már készül eltűnni. Ez alkalmas a látható adatok (beviteli mezők szövegének) mentésére. A viewDidDisappear az animáció befejezése után hívódik meg, amikor a nézet garantáltan nem látható — ideális a vizuális állapothoz nem kapcsolódó erőforrások felszabadításához.
A deinit a viewDidDisappear-ral ellentétben csak az UIViewController objektum memóriában történő megsemmisítésekor hívódik meg. Ha a vezérlő csak el van rejtve (például egy modális ablak takarja), a deinit nem hívódik meg. Ebben a helyzetben a viewDidDisappear az egyetlen pont a befejező műveletek végrehajtására. A teljes erőforrás-felszabadításnak a deinit-ben kell történnie, de a viewDidDisappear felelős az ideiglenes felszabadításért az újbóli megjelenésig.
A SwiftUI használatával történő fejlesztés során a viewDidDisappear metódus nem használatos — helyette a .onDisappear módosító használható, amely hasonló módon működik. A SwiftUI-ban azonban nincs közvetlen vezérlés az életciklus felett, és a fejlesztők a Combine-ra és az State objektumokra támaszkodnak az erőforrások kezeléséhez. Az UIKit alkalmazások esetében a viewDidDisappear továbbra is a fő eszköz a képernyő elrejtésének kezelésére.
Még a tapasztalt iOS-fejlesztők is hibáznak a viewDidDisappear-ral való munka során. Tekintsük át az öt leggyakoribb problémát és azok megelőzésének módjait. Ezen antiminták ismerete segít elkerülni a vezérlők életciklusával kapcsolatos nehezen felderíthető hibákat.
Különös figyelmet igényel a szálbiztonság. Ha a viewDidDisappear a fő szálon hívódik meg (amit az UIKit garantál), de az erőforrások felszabadítása aszinkron műveleteket tartalmaz, szinkronizálni kell a megosztott adatokhoz való hozzáférést. A DispatchQueue.main.async használata a viewDidDisappear-on belül a UI frissítésére egy aszinkron feladat befejezése után — általános, de helyes megközelítés.
Egy másik fontos antiminta — delegált metódusok meghívása a viewDidDisappear-on belül, amelyek új átmenetet vagy modális megjelenítést kezdeményezhetnek. Ez egy ciklust hoz létre, amelyben a viewDidDisappear újra meghívódhat az első hívás befejeződése előtt. Az Apple azt javasolja, hogy kerüljük a modális megjelenítéseket az életciklus metódusokon belül, helyette külön eseménykezelőkbe helyezve azokat.
Gyakran ismételt kérdések
A viewWillDisappear az elrejtési animáció megkezdése előtt hívódik meg, amikor a nézet még látható. A viewDidDisappear — a nézet teljes eltűnése után. Adatok mentéséhez használja a viewWillDisappear-t, erőforrások felszabadításához a viewDidDisappear-t.
Igen, a super.viewDidDisappear(animated) meghívása kötelező. Az UIKit ezt a metódust használja belső értesítésekhez és az átmeneti állapot befejezéséhez. A super hívása nélkül összeomlások lehetségesek az UINavigationController-ben és az UITabBarController-ben.
Igen, interaktív dismiss esetén iOS 13+-ban (lefelé húzás) a metódus nem hívódhat meg, ha a gesztus nem fejeződött be. Az esemény garantált fogadásához használja a UIAdaptivePresentationControllerDelegate delegáltat és a presentationControllerDidDismiss metódust.
A deinit csak az objektum megsemmisítésekor hívódik meg, míg a viewDidDisappear minden elrejtéskor. Erőforrások felszabadításához minden átmenetnél (például értesítésekről leiratkozás) használja a viewDidDisappear-t. A vezérlő eltávolításakor végső tisztításhoz — deinit.
A SwiftUI-ban a viewDidDisappear helyett a .onDisappear { } módosító használatos. Ez a nézet hierarchiából való elrejtésekor hívódik meg. Az UIKit-től eltérően a SwiftUI nem garantálja az onDisappear hívását minden forgatókönyvben az animációk során.
Összefoglalás
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is