İOS UIViewController yaşam döngüsünü anlamak mı istiyorsunuz?


299

Yaşam UIViewControllerdöngüsünü yönetmenin doğru yolunu açıklayabilir misiniz ?

Özellikle, nasıl kullanılacağını bilmek istiyorum Initialize, ViewDidLoad, ViewWillAppear, ViewDidAppear, ViewWillDisappear, ViewDidDisappear, ViewDidUnloadve Disposebir için Mono Touch yöntemler UIViewControllersınıfında.


OSX ViewController ve WindowController için bazı bilgiler veya bağlantılar var mı? Lütfen paylaşın.
Anoop Vaidya

Yanıtlar:


410

Tüm bu komutlar, görünüm denetleyicisini yüklediğinizde / sunduğunuz / gizlediğinizde iOS tarafından uygun zamanlarda otomatik olarak çağrılır. Bu yöntemlerin kendilerine UIViewControllerdeğil, UIViewkendilerine bağlı olduğuna dikkat etmek önemlidir . Yalnızca a kullanarak bu özelliklerden hiçbirini alamazsınız UIView.

Apple'ın sitesinde harika belgeler var . Basitçe söylemek gerekirse:

  • ViewDidLoad- Sınıfı oluşturup xib'ten yüklediğinizde çağrılır. İlk kurulum ve sadece bir kerelik çalışma için idealdir.

  • ViewWillAppear- Görünümünüz görünmeden hemen önce çağrılır, görünümleri görünmeden önce alanları veya istediğiniz işlemleri gizlemek / göstermek için iyi olur. Görünümler arasında gidip geleceğinizden, görünümünüz her ekranda görünmek üzereyken bu çağrılacaktır.

  • ViewDidAppear - Görünüm göründükten sonra çağrılır - bir API'den animasyonlar veya harici veriler yüklenmeye başlamak için harika bir yer.

  • ViewWillDisappear/ DidDisappear- aynı fikri ViewWillAppear/ ' ViewDidAppear.

  • ViewDidUnload/ ViewDidDispose- Objective-C'de, temizlik ve bırakma işlerinizi burada yaparsınız, ancak bu otomatik olarak yapılır, burada yapmanız gereken çok fazla bir şey yoktur.


86
ViewDidLoad yalnızca bir kerelik işler için kullanılmaması gerektiğinden, bu metin biraz yanıltıcıdır. Düşük bellek nedeniyle görünümün boşaltılması ve ardından tekrar yüklenmesi durumunda birkaç kez çağrılabilir.
Ricky Helgesson

4
Görünüm denetleyicisini oluşturduğunuzda / başlattığınızda ViewDidLoad aslında çağrılmaz. İlk kez görünüm denetleyicisinin görünümü ile ilgili bir görünüm yaptığınızda çağrılır. Alt görünüm olarak ekleyin, çerçeveyi ayarlayın, vb. Bir uçtan yüklerken elbette denir.
Jason Grandelli

3
ViewDidAppear - Görünüm göründükten sonra çağrılır - bir animasyon başlatmak veya bir API'dan harici verilerin yüklenmesi için harika bir yer. Veri yüklemeye başlamak için neden iyi bir yer? Neden viewDidLoad?
Anton Chikin

1
viewDidLoad'dan önce belleğe bir uç yüklendiğinde ilk çağrılırsa loadView yöntemi hakkında ne dersiniz?
iHulk

@chakrit bu iyi bir nokta - viewDidAppear (eğer gerekiyorsa) verileri yenilemek için harika bir yerdir. KVO hakkında aynı fikirde değilim, çünkü aslında bir kullanıcı tarafından asla görüntülenmeyen görünümlerde istenmeyen yenilemelere neden olabilir.
Anton Chikin

409

GÜNCELLEME: ViewDidUnload, iOS 6'da kullanımdan kaldırıldı, bu nedenle yanıtı güncelleyin.

UIViewController yaşam döngüsü burada gösterilmiştir:

Bir görünüm denetleyicisinin yaşam döngüsü

Xamarin Native / Mono Touch kullanmanın avantajı, yerel API'ları kullanması ve bu nedenle Apple'ın Dokümantasyonunda bulacağınız ViewController yaşam döngüsünü izlemesidir.


17
ViewWillLayoutSubviews ve viewDidLayoutSubviews bu akış şemasında nereye gider?
Max_Power89

7
Bu diyagram yanlış. viewDidUnload, iOS6'dan beri kullanımdan kaldırıldı: stackoverflow.com/questions/12509102/…
Temmuz

2
Bu gerçekten de yanlış . Yıllar geçtikçe SO'ya basit bir yanlış yanıtın başka bir örneği. Bilgi işlem oldukça statik değildir.
Fattie

187

Bu, en son iOS Sürümleri içindir ( Xcode 9.3, Swift 4.1 ile modifiye edilmiştir ). Aşağıda, yaşam döngüsünü UIViewControllertamamlayan tüm aşamalar verilmiştir .

  • loadView()

  • loadViewIfNeeded()

  • viewDidLoad()

  • viewWillAppear(_ animated: Bool)

  • viewWillLayoutSubviews()

  • viewDidLayoutSubviews()

  • viewDidAppear(_ animated: Bool)

  • viewWillDisappear(_ animated: Bool)

  • viewDidDisappear(_ animated: Bool)

Tüm bu aşamaları açıklayayım.

1. loadView

Bu olay, denetleyicinin yönettiği görünümü oluşturur / yükler. İlişkili bir uç dosyasından veya boş UIViewbulunursa boş bir dosyadan yüklenebilir . Bu, kod içinde görünümlerinizi programlı olarak oluşturmak için iyi bir yer yapar.

Bu, alt sınıfların uç kullanmıyorsa özel görünüm hiyerarşilerini oluşturmaları gereken yerdir. Asla doğrudan çağrılmamalıdır. Bu yöntemi yalnızca programlı olarak görünümler oluşturduğunuzda ve kök görünümü viewözelliğe atadığınızda geçersiz kılın Loadload'u geçersiz kıldığınızda süper yöntemi arama

2. loadViewIfNeeded

Akım görünümü viewControllerhenüz ayarlanmamışsa, bu yöntem görünümü yükler, ancak hatırlar, bu yalnızca iOS> = 9.0'da kullanılabilir. Dolayısıyla, iOS <9.0'ı destekliyorsanız, resmin içine girmesini beklemeyin.

Henüz ayarlanmamışsa görünüm denetleyicisinin görünümünü yükler.

3. viewDidLoad

viewDidLoadGörünümü oluşturulur ve yüklenen belleğe ama görünüm için sınırları henüz tanımlanmamış olduğunda olay sadece denir. Bu, görünüm denetleyicisinin kullanacağı nesneleri başlatmak için iyi bir yerdir.

Görünüm yüklendikten sonra çağrılır. Kodda oluşturulan görünüm denetleyicileri için bu -loadView öğesinden sonra gelir. Bir uçtan arşivlenmemiş görünüm denetleyicileri için bu görünüm ayarlandıktan sonra yapılır.

4. viewWillAppear

Bu olay viewController, görünüm ekranda her görüntülendiğinde bunu bildirir . Bu adımda görünümün tanımlanmış sınırları vardır ancak yön ayarlanmamıştır.

Görünüm görünür hale getirmek üzereyken çağrılır. Varsayılan hiçbir şey yapmaz.

5. viewWillLayoutSubviews

Bu, yaşam döngüsünde sınırların kesinleştiği ilk adımdır. Kısıtlamalar veya Otomatik Düzen kullanmıyorsanız, muhtemelen alt görünümleri burada güncellemek istersiniz. Bu yalnızca iOS> = 5.0 sürümünde kullanılabilir. Dolayısıyla, iOS <5.0'ı destekliyorsanız, resme gelmesini beklemeyin.

Görünüm denetleyicisinin görünümünün layoutSubviews yöntemi çağrılmadan hemen önce çağrılır. Alt sınıflar gerektiği gibi uygulanabilir. Varsayılan bir nop değeridir.

6. viewDidLayoutSubviews

Bu olay, görünüm denetleyicisine alt görünümlerin ayarlandığını bildirir. Alt görünümler oluşturulduktan sonra herhangi bir değişiklik yapmak için iyi bir yerdir. Bu yalnızca iOS> = 5.0 sürümünde kullanılabilir. Dolayısıyla, iOS <5.0'ı destekliyorsanız, resme gelmesini beklemeyin.

Görünüm denetleyicisinin görünümünün layoutSubviews yöntemi çağrıldıktan hemen sonra çağrılır. Alt sınıflar gerektiği gibi uygulanabilir. Varsayılan bir nop değeridir.

7. viewDidAppear

viewDidAppearGörünümde sonra olay yangınlar ekranda sunulur. Bu, bir arka uç hizmetinden veya veritabanından veri almak için iyi bir yer yapar.

Görünüm tamamen ekrana geçtiğinde çağrılır. Varsayılan hiçbir şey yapmaz

8. viewWillDisappear

Sunulan viewWillDisappeargörüş viewControllerkaybolmak, reddetmek, örtmek veya gizlemek üzereyken olay tetiklenir viewController. Bu, ağ aramalarınızı kısıtlayabileceğiniz, zamanlayıcıyı geçersiz kılabileceğiniz veya buna bağlı nesneleri bırakabileceğiniz iyi bir yerdir viewController.

Görünüm kapatıldığında, kapatıldığında veya başka bir şekilde gizlendiğinde çağrılır.

9. viewDidDisappear

Bu, sunulan olay viewControllerkaybolduktan, reddedildikten, kapatıldıktan veya gizlendikten hemen sonra bu olay tetiklendiğinde herkesin ele alabileceği yaşam döngüsünün son adımıdır .

Görünüm reddedildikten, kapatıldıktan veya başka bir şekilde gizlendikten sonra çağrılır. Varsayılan hiçbir şey yapmaz

Şimdi Apple'a göre bu yöntemleri superuygularken söz konusu yöntemin uygulanmasını çağırmayı unutmamalısınız .

UIViewController alt sınıfını kullanıyorsanız, bir NIB kullanmasanız bile bu yöntemin süper uygulamasını çağırmalısınız. (Kolaylık olması açısından, varsayılan init yöntemi bunu sizin için yapar ve bu yöntem bağımsız değişkenlerinin her ikisi için de nil belirtir.) Belirtilen NIB'de, Dosya Sahibi proxy'sinin görünümü, görünüm çıkışı ile görünüm denetleyicisi alt sınıfınıza ayarlanmış olmalıdır ana görünüme bağlı. Bu yöntemi bir nil nib adıyla çağırırsanız, bu sınıfın -loadViewyöntemi, adı görünüm denetleyicinizin sınıfıyla aynı olan bir NIB yüklemeye çalışır. Aslında böyle bir NIB mevcut değilse, daha -setView:önce -viewçağrılmalı veya -loadViewgörünümlerinizi programlı olarak ayarlama yöntemini geçersiz kılmalısınız.

Umarım bu yardımcı olmuştur. Teşekkürler.

GÜNCELLEME - As @ThomasW yorumun içindeki sivri viewWillLayoutSubviewsve viewDidLayoutSubviewsana görünümün subviews yüklendiğinde bir tablo görünümünde veya toplama bakış hücreler yüklendiğinde da örneğin, diğer zamanlarda çağrılacak.

GÜNCELLEME - @Maria yorumda işaret ettiği gibi, açıklaması loadViewgüncellendi


6
viewWillLayoutSubviewsve viewDidLayoutSubviewsana görünümün subviews yüklendiğinde bir tablo görünümü veya toplama bakış hücreler yüklendiğinde aynı zamanda, örneğin, diğer zamanlarda çağrılır.
ThomasW

Bu cevapta küçük bir yanıltıcılık vardır: loadView () her zaman çağrılır, sadece IB'de oluşturulan denetleyiciye yönelik görünümün geçersiz kılınmaması gerekir.
Maria

@Maria Geliştirilebileceğini düşünüyorsanız lütfen devam edin ve yanıtı düzenleyin. Teşekkürler.
Tamamlanma

Varsayılan, yanlış bir şey yapmaz viewWillAppear viewDidAppear viewDidDisappear. Bir noktada super'i aramalısın.
Mick

47

iOS 10,11 (Swift 3.1, Swift 4.0)

Göre UIViewControllerde UIKitgeliştiriciler,

1. loadView ()

Bu, alt sınıfların kullanmıyorsa özel görünüm hiyerarşilerini oluşturmaları gereken yerdir . Asla doğrudan çağrılmamalıdır.

2. loadViewIfNeeded ()

Henüz ayarlanmamışsa görünüm denetleyicisinin görünümünü yükler.

3. viewDidLoad ()

Görünüm yüklendikten sonra çağrılır. Kodda oluşturulan görünüm denetleyicileri için bu -loadView öğesinden sonra gelir. Bir uçtan arşivlenmemiş görünüm denetleyicileri için bu görünüm ayarlandıktan sonra yapılır.

4. viewWillAppear (_ animasyonlu: Bool)

Görünüm görünür hale getirmek üzereyken çağrılır. Varsayılan hiçbir şey yapmaz

5. viewWillLayoutSubviews ()

Görünüm denetleyicisinin görünümünün layoutSubviews yöntemi çağrılmadan hemen önce çağrılır. Alt sınıflar gerektiği gibi uygulanabilir. Varsayılan hiçbir şey yapmaz.

6. viewDidLayoutSubviews ()

Görünüm denetleyicisinin görünümünün layoutSubviews yöntemi çağrıldıktan hemen sonra çağrılır. Alt sınıflar gerektiği gibi uygulanabilir. Varsayılan hiçbir şey yapmaz.

7. viewDidAppear (_ animasyonlu: Bool)

Görünüm tamamen ekrana geçtiğinde çağrılır. Varsayılan hiçbir şey yapmaz

8. viewWillDisappear (_ animasyonlu: Bool)

Görünüm kapatıldığında, kapatıldığında veya başka bir şekilde gizlendiğinde çağrılır. Varsayılan hiçbir şey yapmaz

9. viewDidDisappear (_ animasyonlu: Bool )

Görünüm reddedildikten, kapatıldıktan veya başka bir şekilde gizlendikten sonra çağrılır. Varsayılan hiçbir şey yapmaz

10. viewWillTransition (boyuta göre: CGSize, koordinatör ile: UIViewControllerTransitionCoordinator)

Görünüm Geçiş yaparken çağrılır.

11. willMove (toParentViewController üst öğesi: UIViewController?)

12. didMove (toParentViewController üst öğesi: UIViewController?)

Bu iki yöntem, alt denetleyiciler arasında geçiş yaparken kapsayıcı alt sınıflarının çağırması için geneldir. Geçersiz kılmaları durumunda, geçersiz kılmalar süper çağırmayı sağlamalıdır.

Bu yöntemlerin her ikisinde de ana argüman, bir çocuk ebeveyninden çıkarıldığında sıfırdır; aksi takdirde yeni ana görünüm denetleyicisine eşittir.

13. didReceiveMemoryWarning ()

Üst uygulama bir bellek uyarısı aldığında çağrılır. İOS 6.0'da artık varsayılan olarak görünümü temizlemeyecek.


2
Stackoverflow tüm bu iş parçacığından gelen tüm yanlış ve eksik cevapları temizlemeyecek gerçekten çok üzücü. Cevabınız yöntem çağrıları kadar eksiksiz görünüyor, bu yüzden sizinkinin doğru olduğunu varsayalım ve bununla çalışacağım.
Logicsaurus Rex

Aşağıda nibbelirtildiği gibi bir nedir loadView?
Petrus Theron

2
@LogicsaurusRex Kabul ediyorum. SO'nun soruları kopyalar veya korumalı olarak işaretlediği gibi, cevapları eski veya eski
rmp251

Yukarıdaki 5. Nokta yanlış. viewWillLayoutSubviews()ViewController'ın görüntüleme nesnesi layoutSubviews()yöntemini çağırmadan önce çağrılır
williamukoh

28

İOS 6'dan itibaren. Yeni diyagram aşağıdaki gibidir:

resim açıklamasını buraya girin


1
Bu görünüme "A" deyin. "A" kaybolurken görünen ikinci bir "B" görünümünü düşünün. "B.viewWillAppear", "A.viewDidDisappear" dan önce veya sonra mı? Ve bu ikisinin düzeninin değiştiği durumlar var mı?
ToolmakerSteve

Görünüşe göre yeni görünüm (B) willApear kaybolmadan önce çağrılır. İkinci soru için. Bakmak için biraz zamana ihtiyacım var.
Saad

21

UIViewController'ın yaşam döngüsünden sorumlu yöntemlere odaklanalım :

  • Oluşturma:

    - (void)init

    - (void)initWithNibName:

  • Oluşturmayı görüntüle:

    - (BOOL)isViewLoaded

    - (void)loadView

    - (void)viewDidLoad

    - (UIView *)initWithFrame:(CGRect)frame

    - (UIView *)initWithCoder:(NSCoder *)coder

  • Görünüm durumunun değiştirilmesi:

    - (void)viewDidLoad

    - (void)viewWillAppear:(BOOL)animated

    - (void)viewDidAppear:(BOOL)animated

    - (void)viewWillDisappear:(BOOL)animated

    - (void)viewDidDisappear:(BOOL)animated

    - (void)viewDidUnload

  • Bellek uyarı işleme:

    - (void)didReceiveMemoryWarning

  • Deallocation

    - (void)viewDidUnload

    - (void)dealloc

UIViewController'ın yaşam döngüsü diyagramı

Daha fazla bilgi için lütfen UIViewController Sınıf Referansına bakınız .


19

Yöntemlerde viewWillLayoutSubviewsve viewDidLayoutSubviewsdiyagramlarda belirtilmemiştir, ancak bunlar viewWillAppearve arasında adlandırılır viewDidAppear. Birden çok kez çağrılabilirler.


Ayrıca, ana görünümün alt görünümleri yüklendiğinde, örneğin bir tablo görünümü veya toplama görünümü hücreleri yüklendiğinde bunlar da çağrılacaktır.
ThomasW

16

Haider'ın cevabı iOS 6 öncesi için doğrudur. Ancak, iOS 6'dan itibaren viewDidUnload ve viewWillUnload asla çağrılmaz. Docs durum: "Görüntüleme artık düşük bellek koşullarında ve bu yöntem asla denir böylece temizlenir."


ViewWillDisappear, ViewDidDisappear, Dispose bir kesme noktası koyarak çalıştı. Ama PresentViewController () yöntemi ile gezinti zaman hiçbiri çağrılıyor. Sebebi ne olabilir?
Sreeraj

1
Bağlantı çalışmıyor ... Peki işletim sistemi düşük bellekte ne yapıyor?
Oğul

Onları diske kaydeder mi?
Ian Warburton

16

Burada çok sayıda eski ve eksik bilgi var. İçin IOS 6 ve daha yeni ancak:

  1. loadView[A]
  2. viewDidLoad[A]
  3. viewWillAppear
  4. viewWillLayoutSubviews sınırlar ilk kez kesinleştiğinde
  5. viewDidLayoutSubviews
  6. viewDidAppear
  7. * viewWillLayoutSubviews[B]
  8. * viewDidLayoutSubviews[B]

Dipnotlar:

(a) - elle sırasında görünümünüzü dışarı nil ise didReceiveMemoryWarning, loadViewve viewDidLoadyine çağrılacak. Yani, varsayılan olarak loadViewve viewDidLoadher görünüm denetleyicisi örneği için yalnızca bir kez çağrılır.

(b) Ek 0 veya daha fazla kez çağrılabilir .


1
viewWillLayoutSubviewsve viewDidLayoutSubviewsana görünümün subviews yüklendiğinde bir tablo görünümü veya toplama bakış hücreler yüklendiğinde aynı zamanda, örneğin, diğer zamanlarda çağrılır.
ThomasW


0

Gereğince Apple'ın doc - Görünüm Kontrolörleri ile Çalışma - - Başlangıç iOS Uygulamalar (Swift) Gelişmekte View Controller Ömrü anlama

viewDidLoad()- Görünüm denetleyicisinin içerik görünümü (görünüm hiyerarşisinin üst kısmı) bir storyboard'dan oluşturulduğunda ve yüklendiğinde çağırılır. … Görünüm denetleyicinizin gerektirdiği ek ayarları yapmak için bu yöntemi kullanın.

viewWillAppear()- Görünüm denetleyicisinin içerik görünümü uygulamanın görünüm hiyerarşisine eklenmeden hemen önce çağrılır. İçerik görünümü ekranda gösterilmeden önce yapılması gereken işlemleri tetiklemek için bu yöntemi kullanın

viewDidAppear()- Görünüm denetleyicisinin içerik görünümü, uygulamanın görünüm hiyerarşisine eklendikten hemen sonra çağrılır. Görünüm ekranda veri getirilir getirilmez veya veri gösteriliyor gibi gerçekleşmesi gereken işlemleri tetiklemek için bu yöntemi kullanın.

viewWillDisappear()- Görünüm denetleyicisinin içerik görünümü uygulamanın görünüm hiyerarşisinden kaldırılmadan hemen önce çağrılır. Değişiklikleri işleme veya ilk yanıtlayıcı durumunu terk etme gibi temizleme görevlerini gerçekleştirmek için bu yöntemi kullanın.

viewDidDisappear()- Görünüm denetleyicisinin içerik görünümü uygulamanın görünüm hiyerarşisinden kaldırıldıktan hemen sonra çağırılır. Ek ayırma etkinlikleri gerçekleştirmek için bu yöntemi kullanın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.