Jaki jest proces urodzenia UIViewController (która metoda następuje po której)?

Istnieje wiele metod do nadpisania, takich jak initWithNibname:, awakeFromNib, loadView, viewDidLoad, viewDidAppear:, layoutSubviews, i po prostu nie mogę się zdecydować, w jakiej kolejności dostaje te metody nazywa.

Po prostu nadpisuję jeden z nich "na pamięć". Jakieś szczegółowe wyjaśnienia?
Author: Harris, 2011-02-24

7 answers

Wiele się dzieje za kulisami z Cocoa view i ViewController management .

1. Obiekt viewController

Najbardziej podstawowy, viewController jest ogólnym obiektem kontrolera. Gdy po raz pierwszy zostanie przydzielona inicjalizowana, nie ma z nią skojarzonego obiektu view. Widok jest tworzony tylko wtedy, gdy (i jeśli) jest wymagany. Tak więc, bez uwzględnienia widoku, cykl życia kontrolera viewController jest taki sam jak każdy inny obiekt:

UIViewController * myVC = [[UIViewController alloc] initWith...];
...
[myVC release];

Wyznaczonym inicjalizatorem dla kontrolerów viewcontrollerów jest -initWithNibname:bundle:. Jeśli określisz nasadkę, viewController może automatycznie załadować swój widok z tej nasadki i podłączyć dowolne iboutlety, które zdefiniowałeś(więcej szczegółów znajdziesz poniżej).

2. Ładowanie i rozładowywanie widoku

ViewController załaduje swój widok zgodnie z wymaganiami. Zwykle dzieje się tak, gdy metoda -view jest wywoływana po raz pierwszy i może się zdarzyć w dowolnym momencie w Twoim program, w zależności od sposobu inicjalizacji interfejsu użytkownika. Widok może również zostać zniszczony i przeładowany kilka razy w ciągu życia programu, w zależności od sposobu zarządzania interfejsem użytkownika. Gdy kontroler ViewController stwierdzi, że jego widok jest wymagany, ale nie jest jeszcze załadowany, zostanie wywołana metoda -loadView. Podstawowy przepływ wiadomości przebiega w następujący sposób:

view
  loadView
  viewDidLoad

Zauważ, że jeśli nadpiszesz metodę -view, -loadView i viewDidLoad nie zostaną wywołane automatycznie. Jeśli nadpisujesz -loadView, musi ustawić właściwość viewController view. W przeciwnym razie, następne wywołanie -view ponownie uruchomi proces ładowania.

Widok może być również rozładowany w dowolnym momencie w trakcie życia programu, po prostu ustawiając właściwość view na nil. Domyślna implementacja -didReceiveMemoryWarning zrobi to automatycznie, o ile widok nie ma superview (tzn. jeśli nie jest obecnie częścią aktywnego heirarchii widoku). Przepływ wiadomości przebiega następująco następuje:

view = nil
   viewDidUnload

2a. ładowanie widoku programowo

Jeśli zdecydujesz się nadpisać -loadView, możesz utworzyć widok, podwinięcia, inne kontrolery widoku i dowolne połączenia między tymi obiektami w dowolny sposób. Oczywiście oznacza to, że jesteś również odpowiedzialny za zarządzanie pamięcią w odniesieniu do obiektów, które tworzysz. Jeśli twoja podklasa nadpisuje -loadView, powinna być zainicjalizowana za pomocą {[14] } zarówno dla nibName, jak i bundle.

2b. Ładowanie widok ze stalówki

Jeśli używasz pliku nib, Domyślna implementacja -loadView automatycznie otworzy ten plik nib, utworzy instancje jego obiektów, doda połączenia między nimi i zajmie się zarządzaniem pamięcią.

Sprawy stają się nieco bardziej skomplikowane z plikami stali, ponieważ tak wiele dzieje się za kulisami. Metoda -awakeFromNib jest wywoływana dla każdego obiektu , który jest tworzony podczas ładowania pliku nib i nie ma gwarancji, że drugi obiekty w pliku nib zostaną w pełni załadowane podczas jego wywoływania.

3. Wyświetlanie widoków

-viewWillAppear:, -viewDidAppear:, -viewWillDisappear: i -viewDidDisappear: są wywoływane tylko wtedy, gdy widok jest wyświetlany lub ukryty na ekranie, szczególnie podczas animowanych przejść z jednego widoku do drugiego. Metody te mogą być wywoływane wiele razy w ciągu życia programu, ponieważ widoki są zamieniane w schemacie nawigacji.

4. Zobacz układ

The -layoutSubviews metoda jest nie częścią UIViewController. Jest ona wywoływana dla UIView obiektów, gdy ich granice zostały zmienione. Jeśli używasz niestandardowej podklasy UIView w swoim programie, ta metoda może być używana do tworzenia niestandardowego układu podkategorii, zamiast polegać na domyślnych metodach automatyzacji Cocoa.

5. Składając wszystko razem

Ze względu na złożoność procesu istnieje wiele różnych sposobów, ale normalna oś czasu może wyglądać mniej więcej tak:]}
-[viewController initWithNibname:Bundle:]
-[viewController awakeFromNib]
-[viewController loadView]
-[view awakeFromNib]
-[viewController viewDidLoad]
-[viewController viewWillAppear]
-[viewController viewDidAppear]
...
-[viewController viewWillDisappear]  // user navigated away
-[viewController viewDidDisappear]
...
-[viewController viewWillAppear]     // user navigated back
-[viewController viewDidAppear]
...
-[viewController viewWillDisappear]  // user navigated away
-[viewController viewDidDisappear]
...
-[viewController setView:nil]        // memory warning, perhaps
-[viewController viewDidUnload]
...
-[viewController loadView]           // user navigated back
-[view awakeFromNib]
-[viewController viewDidLoad]
-[viewController viewWillAppear]
-[viewController viewDidAppear]
...
 171
Author: e.James,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-20 18:18:20

Przejrzałem to ostatnio i stworzyłem projekt testowy: https://github.com/Janek2004/ViewControllerTest

Uruchom projekt na symulatorze iOS, aby zobaczyć kolejność wykonywania metod podklasy UIViewController. Kolejność może być inna, gdy używamy pliku Nib zamiast storyboard lub load view controller programowo.

  1. -[ViewController initWithCoder:] Niearchive danych z nib lub storyboard
  2. -[ViewController awakeFromNib] przygotowuje odbiornik do obsługi po załadowaniu go z archiwum Interface Builder lub nib plik.
  3. -[ViewController loadView] nigdy nie należy wywoływać tej metody bezpośrednio. Kontroler widoku wywołuje tę metodę, gdy jego widok property is requested but is currently nil. Metoda ta ładuje lub tworzy widok i przypisuje go do właściwości view.
  4. -[ViewController viewDidLoad] metoda ta jest wywoływana po tym, jak kontroler widoku załadował swoją hierarchię widoków do pamięci.
  5. -[ViewController viewWillAppear:] metoda ta jest wywoływana przed dodaniem widoku odbiornika do hierarchii widoku i przed wszystkie animacje są skonfigurowane do wyświetlania widoku.
  6. -[ViewController viewWillLayoutSubviews] wywołane, aby powiadomić kontroler widoku, że jego Widok ma zamiar układać jego podview.Gdy a granice widoku zmieniają się, widok dostosowuje położenie jego podwidań. Kontroler widoku może zastąp tę metodę, aby wprowadzić zmiany przed widok przedstawia swoje podglądy.
  7. -[ViewController viewDidLayoutSubviews] wywołane, aby powiadomić kontroler widoku, że jego widok właśnie rozplanował swoje podwoje. Kiedy zmiana granic dla widoku kontrolera widoku, widok dostosowuje pozycji jego podwidywań, a następnie system wywołuje tę metodę. Jednak wywołanie tej metody nie wskazuje, że dostosowano poszczególne układy podwidań widoku. Każdy subview jest odpowiedzialny za dostosowanie własnego układu.
  8. -[ViewController Viewdidappear:] powiadamia kontroler widoku, że jego Widok został dodany do hierarchii widoków. Możesz nadpisać tę metodę wykonywanie dodatkowych zadań związanych z prezentacją widoku.

  9. -[ViewController Viewwilldisappear:] powiadamia kontroler widoku, że jego Widok ma zostać usunięty z hierarchii widoków.To metoda jest wywoływana w odpowiedzi na usunięcie widoku z widok hierarchia. Ta metoda jest wywoływana przed usunięciem widoku i zanim jakiekolwiek animacje zostaną skonfigurowane. Powiadamia widok kontrolera, że jego Widok został dodany do hierarchii widoków. Możesz zastąp tę metodę, aby wykonać dodatkowe zadania związane z przedstawiam widok.

  10. - [ViewController viewDidDisappear:] powiadamia kontroler widoku, że jego Widok został usunięty z hierarchii widoków.
 35
Author: Janusz Chudzynski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-05 17:20:58

Innym kluczowym momentem w procesie jest wywołanie layoutSubviews na dowolnych podviewach. W tym momencie, a nie wcześniej, wszelkie ograniczenia skonfigurowane w storyboard zostały zastosowane. Jeśli chcesz wprowadzić zmiany w podwidywaniach widoku na podstawie jego ograniczonych współrzędnych, musisz to zrobić w layoutSubviews. Jeśli zrobisz to w viewDidLayoutSubviews, to będzie to za wcześnie, ponieważ te podview nie mają jeszcze zastosowanych ograniczeń (ponieważ jak mówi dokumentacja " każdy subview jest odpowiedzialny za dostosowanie własnego układu".) A jeśli zrobisz to w viewDidAppear, będzie to oczywiście za późno, ponieważ użytkownik zobaczy, że Twoje podviewy zmieniają współrzędne. Tak więc drugim ważnym krokiem w tym procesie jest:

-viewController viewWillAppear
-viewController viewWillLayoutSubviews
-viewController viewDidLayoutSubviews
---> viewController.[any subview] layoutSubviews
-viewController viewDidAppear  
 8
Author: Harris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-22 03:25:08

Z Dokumentacji Apple UIViewController:

Kiedy definiujesz nową podklasę UIViewController, musisz określić widoki, którymi kontroler będzie zarządzał. Istnieją dwa wzajemnie wykluczające się sposoby określenia tych widoków: ręcznie lub za pomocą pliku nib. Jeśli widoki zostaną określone ręcznie, należy zaimplementować metodę loadView i użyć jej do przypisania głównego obiektu widoku do właściwości view. Jeśli określisz widoki za pomocą pliku nib, nie możesz nadpisać loadView, ale zamiast tego należy utworzyć plik nib w Interface Builder, a następnie zainicjować obiekt kontrolera widoku za pomocą metody initwithnibname: bundle:. Tworzenie widoków za pomocą pliku nib jest często prostsze, ponieważ można użyć aplikacji Interface Builder do tworzenia i konfigurowania widoków graficznie(w przeciwieństwie do programowego). Obie techniki mają jednak ten sam efekt końcowy, który polega na stworzeniu odpowiedniego zestawu widoków i wyeksponowaniu ich za pomocą właściwości view.

Z top of my head:

  1. initWithNibname
  2. loadView (ładuj rzeczy ręcznie)
  3. viewDidiLoad
  4. viewDidAppear

Nie wiadomo gdzie wchodzi layoutSubviews

 4
Author: LordT,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-24 17:09:55

Generalnie rozwiązuję to pytanie, umieszczając NSLog (lub punkty przerwania) we wszystkich tych delegatach, w tym delegat uruchamiania aplikacji, i postępując zgodnie z kolejnością w debuggerze.

 1
Author: hotpaw2,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-24 16:46:53
-- This is related to view only:
-viewWillAppear:
-viewDidAppear: 
-viewWillDisappear: and 
-viewDidDisappear: 

are only called when the view is being displayed.

-viewController viewDidLoad
-viewController viewWillAppear
-viewController viewDidAppear

other methods

-viewController viewDidDisappear
-viewController viewWillDisappear 
-viewController viewDidUnload
 1
Author: Ram S,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-21 08:56:59

Chcę podziękować E. James za jego doskonały opis. Nie mogę jeszcze skomentować posta, ale aby uzyskać szybką wizualną ilustrację, zapoznaj się z tym schematem przepływu w Przewodniku programowania kontrolera widoku. I zdaję sobie sprawę, że jest to off-topic, ale dla Wykres sekwencji uruchamiania aplikacji , zapoznaj się z przewodnikiem programowania aplikacji na iOS.

 0
Author: Chris Conover,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-03 22:00:46