ViewController Lifecycle, UIKit'in iOS'ta ekranları yönetirken otomatik olarak çağırdığı yöntemlerin sırasıdır. Apple Belgeleri'ne göre, her UIViewController öngörülebilir bir durum kümesinden geçer: View oluşturmadan görünme ve kaybolmaya kadar. Anlamak bu yöntemlerin sırasını ve amacını anlamak, kararlı bir iOS uygulaması çalışması için gerekli bir koşuldur.
Anahtar noktalar
ViewController Lifecycle, UIViewController'ın varlığı boyunca UIKit'ten aldığı yöntemler kümesidir. Bir iOS uygulamasındaki her ekran sırasıyla oluşturma, View yükleme, ekranda görünme, kaybolma ve bellek serbest bırakma aşamalarından geçer. UIKit her aşamada ilgili yöntemleri otomatik olarak çağırır ve geliştirici kendi mantığını eklemek için bunları geçersiz kılar.
UIViewController mimarisi UIKit'in temelidir ve SwiftUI çağında bile geçerliliğini korur — birçok proje hala klasik yaklaşımı veya hibrit bir mimariyi kullanır. Lifecycle'ı anlamak, subviews'lerin ne zaman kullanılabilir olduğunu, düzeni değiştirmenin ne zaman güvenli olduğunu ve ekran göründüğünde veya kaybolduğunda hangi işlemlerin yapılması gerektiğini tahmin etmenizi sağlar.
Yaşam döngüsündeki her yöntemin belirli bir amacı vardır: bazıları denetleyicinin tüm ömrü boyunca yalnızca bir kez çağrılır, diğerleri — her görünme veya kaybolmada. Yöntemler arasında mantığı karıştırmak, bulunması zor hatalara yol açar: bellek sızıntıları, yanlış veri güncellemeleri ve gereksiz ağ istekleri.
Altı yöntem UIViewController'ın tam yaşam döngüsünü oluşturur. Çağrı sırası sabittir ve gezinme yöntemine bağlı değildir — push, present veya unwind segue'in hepsi aynı programı izler.
loadView döngünün ilk yöntemidir ve denetleyicinin View'i henüz mevcut olmadığında çağrılır. Storyboard kullanıyorsanız, UIKit otomatik olarak xib dosyasından View'i yükler. Arabirimi programatik olarak oluştururken, kök View'i manuel olarak atayarak bu yöntemi geçersiz kılarsınız. Çoğu projede loadView'e dokunulmaz — iş viewDidLoad'da yapılır.
loadView'i geçersiz kılmak yalnızca belirli durumlarda gereklidir: tüm arabirimin Storyboard olmadan kodda oluşturulduğu veya kök View'in standart olmayan bir sınıftan olması gerektiği durumlarda. Apple, geçersiz kılarken super.loadView'i çağırmamanızı önerir — View oluşturma sorumluluğunu tamamen üstlenirsiniz.
override func loadView() {
view = UIView()
view.backgroundColor = .white
}
viewDidLoad döngünün en sık kullanılan yöntemidir. View belleğe yüklendikten sonra ancak henüz ekranda görüntülenmeden önce bir kez çağrılır. Burada subviews'ler yapılandırılır, tablolar verilerle doldurulur, hücreler kaydedilir ve denetleyicinin tüm ömrü boyunca süren bildirimlere abone olunur.
Önemli bir özellik: ekran tekrar gösterildiğinde viewDidLoad yeniden çağrılmaz. Ekran her göründüğünde verileri güncellemeniz gerekiyorsa — viewWillAppear kullanın. viewDidLoad'a yalnızca temel yapılandırma için gerekli olan tek seferlik işlemleri koyun.
viewWillAppear, View kullanıcıya görünür hale gelmeden hemen önce her seferinde çağrılır. Bu yöntem, görünürlüğün animasyonlu olup olmadığını belirten bir animated parametresi alır. Burada veriler güncellenir, tablolar yeniden yüklenir, NavigationBar yapılandırılır ve uygulama durumuna göre öğeler gösterilir veya gizlenir.
Ekranlar arasında durum senkronizasyonu için viewWillAppear kullanın: kullanıcı önceki ekranda verileri değiştirmiş olabilir, bu yöntem arabirimi güncellemek için doğru yerdir. viewWillAppear'ın her çağrısı, alt denetleyiciden dönerken bile ekran görünürlüğünden önce gelir.
viewDidAppear, View'in ekranda tamamen göründüğünü ve tüm geçiş animasyonlarının tamamlandığını bildirir. Bu noktada ekran etkileşime hazırdır — kullanıcı tüm arabirimi görür ve onunla etkileşime geçebilir. Bu yöntem, görünürlükten sonra başlaması gereken animasyonları başlatmak, zamanlayıcıları başlatmak ve analiz gösterimlerini izlemek için uygundur.
viewWillAppear'ın aksine, viewDidAppear ekranın yalnızca görünür değil aynı zamanda tamamen işlenmiş olduğunu garanti eder. viewWillAppear'da bir animasyon başlatırsanız, UIKit geçişi henüz tamamlamadığı için bazı kareler atlanabilir. Pürüzsüz animasyonlar için viewDidAppear kullanın.
viewWillDisappear, View ekrandan kaybolmadan önce çağrılır — başka bir denetleyiciye geçerken, modal pencereyi kapatırken veya uygulamayı askıya alırken. Burası durumu kaydetmek, bildirimlerden aboneliği iptal etmek, aktif süreçleri durdurmak ve ekran görünür olmadığında ihtiyaç duyulmayan kaynakları serbest bırakmak için doğru yerdir.
Hatırlanması önemlidir: viewWillDisappear, View'in sonunda kaybolacağını garanti etmez — jest iptal edilebilir. Bu nedenle, kritik verileri yalnızca fiili kaybolmadan sonra çağrılan viewDidDisappear'da da kaydedin.
viewDidDisappear, görünme ve kaybolma döngüsünü tamamlar. View ekrandan gizlendikten sonra çağrılır. Bu yöntemde animasyonlar nihayet durdurulur, geçici nesneler kaldırılır ve viewWillDisappear'da başlatılan veri kaydetme onaylanır.
Bu yöntem ayrıca denetleyicinin deinit'inden önce gelir — UIViewController'ınız yok ediliyorsa, viewDidDisappear deinit çağrılmadan önceki son Lifecycle yöntemi olacaktır. Nesne yok edilmeden önce gerçekleşmesi gereken son temizlik için kullanın.
Çağrıların sırası, ekranın nasıl göründüğüne bağlıdır: ilk kez, geri dönerken veya modal olarak sunulduğunda. UIKit perspektifinden üç ana senaryoyu ele alalım.
Bir ekran ilk kez göründüğünde, UIKit tam oluşturma döngüsünden geçer: loadView çağrılır, ardından viewDidLoad, sonra görünme animasyonu başlar. Animasyon sırasında viewWillAppear çağrılır ve tamamlandıktan sonra — viewDidAppear. Bu, loadView'den viewDidAppear'a kadar tüm yöntemlerin sırayla tetiklendiği tek senaryodur.
override func viewDidLoad() {
super.viewDidLoad()
print("viewDidLoad — View belleğe yüklendi")
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
print("viewWillAppear — Yakında görünecek")
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print("viewDidAppear — Ekran tamamen görünür")
}
Kullanıcı önceki bir ekrana geri döndüğünde, UIKit viewDidLoad'ı tekrar çağırmaz — View zaten bellekte yüklüdür. Bunun yerine, geri dönen ekranda yalnızca viewWillAppear ve viewDidAppear çağrılır ve mevcut ekranda — viewWillDisappear ve viewDidDisappear. loadView ve viewDidLoad, ekran gezinme yığınında zaten bulunduğu için atlanır.
Modal sunum aynı kuralları izler: yeni denetleyici ilk görünürlükte tam döngüden geçerken, mevcut denetleyici viewWillDisappear ve viewDidDisappear alır. Dismiss'te sıra tersine döner: geri dönen denetleyici tekrar viewWillAppear ve viewDidAppear alırken, kaldırılan denetleyici son yöntemleri alır. Bu davranış, UIKit'teki tüm geçiş türleri için tek tiptir.
Lifecycle'ı anlamanın kod kalitesini ve kullanıcı deneyimini doğrudan etkilediği dört temel senaryoyu inceleyelim. Her senaryo için önerilerle birlikte bir örnek sunuyoruz.
viewDidLoad, ekran görünürlüğüne bağlı olmayan ilk kurulum için yerdir. Burada collectionView yapılandırılır, hücreler için nib dosyaları kaydedilir, veri kaynakları ve düzenler oluşturulur. Ağdan veri yüklüyorsanız, viewDidLoad'da yalnızca isteği başlatmak ve ekran görüntülenmeye hazır olduğunda viewWillAppear'da UI'yi güncellemek daha iyidir.
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(
MyCell.self,
forCellReuseIdentifier: MyCell.identifier
)
viewModel.loadInitialData()
}
Ekran her göründüğünde veri senkronizasyonu için viewWillAppear kullanın. Örneğin, kullanıcı önceki ekranda ayarları değiştirmiş olabilir, burada görüntülenen değerler güncellenir, tablo yeniden yüklenir ve NavigationBar durumu ayarlanır. Bu, ekranın herhangi bir gezinme senaryosunda her zaman güncel verileri göstermesini garanti eder.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tableView.reloadData()
navigationController?.setNavigationBarHidden(false, animated: animated)
}
viewDidAppear, kullanıcının ekranı gördükten sonra başlaması gereken animasyonları başlatmak için idealdir. Burada ayrıca analitik olayları da gönderirsiniz: ekran görüntüleme, onboarding başlatma veya video oynatma başlatma. Geçiş tamamlanmadan önce animasyon başlatmak takılma yapan bir arayüze yol açar — UIKit'in yeterli sayıda kare hazırlamak için zamanı olmaz.
viewWillDisappear'da taslaklar kaydedilir, zamanlayıcılar durdurulur ve NotificationCenter'dan abonelik iptal edilir. Bu, ekranın hala görünür olduğu ve kullanıcı bağlamı gerektiren işlemler için erişilebilir olduğu son andır. Kritik veriler için, iptal edilen jestlere karşı koruma olarak ek olarak viewDidDisappear'ı da kullanın.
Yaşam döngüsü yöntemlerinin yanlış kullanımı, iOS uygulamalarında hataların en yaygın kaynaklarından biridir. UIViewController ile çalışmanın farklı aşamalarında geliştiricilerin yaptığı başlıca hataları inceleyelim.
İlk hata — Storyboard kullanırken init veya loadView'da subviews oluşturmak. Interface Builder kullanıyorsanız, gereksiz yere loadView'i geçersiz kılmayın. Bir storyboard varken loadView'da View oluşturmak, xib dosyasının görmezden gelinmesine ve boş bir ekrana yol açar.
İkinci hata — viewDidLoad'da klavye bildirimlerine abone olup aboneliği iptal etmemek. UIResponder.keyboardWillShowNotification'a abone olduysanız ancak ekran gizlendiğinde aboneliği iptal etmediyseniz, blok denetleyicinin deinit'inden sonra bile çağrılmaya devam eder — bu, uygulama çökmesi potansiyeli olan bir bellek sızıntısıdır.
Üçüncü hata — ekran görünmeden önce başlatılan zamanlayıcılar ve ağ istekleri. View henüz görünür değilken görüntü yüklemek veya animasyonlar gerçekleştirmek kaynak israfıdır. Görsel güncellemeleri viewWillAppear veya viewDidAppear'a taşıyın.
Dördüncü hata — verileri yalnızca viewWillDisappear'da kaydetmek. Etkileşimli bir pop jestiyle kullanıcı bir kaydırma başlatabilir ve iptal edebilir — yöntem çağrıldı ancak ekran kaybolmadı. Kritik kaydetmeyi viewDidDisappear veya applicationDidEnterBackground işleyicisinde tekrarlayın.
Sıkça Sorulan Sorular
Bir kez — View belleğe yüklendikten sonra. Ekran tekrar göründüğünde viewDidLoad çağrılmaz. View'i yeniden oluşturmanız gerekiyorsa, denetleyici yok edilmeli ve yeniden oluşturulmalıdır.
UIKit, yaşam döngüsünün doğru çalışması için super.viewDidLoad çağrısını gerektirir. Bu olmadan, düzen güncellemeleri ve geçiş yönetimiyle ilgili sorunlar ortaya çıkabilir. Yöntem içinde her zaman önce super'i çağırın.
Önerilmez. Denetleyici Storyboard'dan başlatılırsa, UIKit otomatik olarak xib'den View'i yükler. loadView'i geçersiz kılmak bu süreci iptal eder ve storyboard'unuz görmezden gelinir.
viewDidLoad veya viewWillAppear'da abone olun ve viewWillDisappear veya viewDidDisappear'da aboneliği iptal edin, closure'larla bellek sızıntılarını önlemek için self'e zayıf bir referans kullanın.
Force quit işlemi aniden sonlandırır — UIKit'in Lifecycle yöntemlerini çağırmak için zamanı olmaz. Verileri kaydetmek için AppDelegate'te UIApplication.willTerminateNotification bildirimini kullanın.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun