Ogólnie system powinien obsługiwać tworzenie instancji kontrolera widoku z scenorysem. To, czego chcesz, to przechodzenie przez hierarchię viewController, przechwytując odwołanie do self.window.rootViewController
kontrolerów widoku, w przeciwieństwie do inicjowania kontrolerów widoku, które powinny być już poprawnie zainicjowane, jeśli poprawnie skonfigurowałeś scenorys.
Powiedzmy, że rootViewController
jest to kontroler UINavigationController, a następnie chcesz wysłać coś do kontrolera widoku z góry, zrobiłbyś to w następujący sposób w AppDelegate didFinishLaunchingWithOptions
:
UINavigationController *nav = (UINavigationController *) self.window.rootViewController;
MyViewController *myVC = (MyViewController *)nav.topViewController;
myVC.data = self.data;
W Swift, jeśli byłoby bardzo podobne:
let nav = self.window.rootViewController as! UINavigationController;
let myVC = nav.topViewController as! MyViewController
myVc.data = self.data
Naprawdę nie powinieneś inicjować kontrolerów widoku przy użyciu identyfikatorów scenorysu od delegata aplikacji, chyba że chcesz ominąć normalny sposób ładowania scenorysu i samodzielnie załadować całą scenorys. Jeśli musisz zainicjować sceny z AppDelegate, najprawdopodobniej robisz coś nie tak. Chodzi mi o to, że wyobraź sobie, że z jakiegoś powodu chcesz wysłać dane do kontrolera widoku w dół stosu, AppDelegate nie powinien sięgać daleko do stosu kontrolera widoku, aby ustawić dane. To nie jego sprawa. To biznes to rootViewController. Pozwól, aby rootViewController obsługiwał własne elementy podrzędne! Tak więc, gdybym ominął normalny proces ładowania scenorysu przez system, usuwając odniesienia do niego w pliku info.plist, co najwyżej utworzyłbym instancję rootViewController za pomocąinstantiateViewControllerWithIdentifier:
i prawdopodobnie jego katalog główny, jeśli jest to kontener, taki jak UINavigationController. To, czego chcesz uniknąć, to tworzenie wystąpień kontrolerów widoku, które zostały już utworzone przez scenorys. To jest problem, który widzę często. Krótko mówiąc, nie zgadzam się z zaakceptowaną odpowiedzią. Jest to niepoprawne, chyba że plakaty oznaczają usunięcie ładowania storyboardu z info.plist, ponieważ w przeciwnym razie załadujesz 2 storyboardy, co nie ma sensu. Prawdopodobnie nie jest to wyciek pamięci, ponieważ system zainicjował scenę główną i przypisał ją do okna, ale potem przyszedłeś, ponownie utworzyłeś instancję i przypisałeś ją ponownie. Twoja aplikacja ma zły start!