Generally, the system should be handling view controller instantiation with a storyboard. What you want is to traverse the viewController hierarchy by grabbing a reference to the self.window.rootViewController
as opposed to initializing view controllers, which should already be initialized correctly if you've setup your storyboard properly.
So, let's say your rootViewController
is a UINavigationController and then you want to send something to its top view controller, you would do it like this in your AppDelegate's didFinishLaunchingWithOptions
:
UINavigationController *nav = (UINavigationController *) self.window.rootViewController;
MyViewController *myVC = (MyViewController *)nav.topViewController;
myVC.data = self.data;
In Swift if would be very similar:
let nav = self.window.rootViewController as! UINavigationController;
let myVC = nav.topViewController as! MyViewController
myVc.data = self.data
You really shouldn't be initializing view controllers using storyboard id's from the app delegate unless you want to bypass the normal way storyboard is loaded and load the whole storyboard yourself. If you're having to initialize scenes from the AppDelegate you're most likely doing something wrong. I mean imagine you, for some reason, want to send data to a view controller way down the stack, the AppDelegate shouldn't be reaching way into the view controller stack to set data. That's not its business. It's business is the rootViewController. Let the rootViewController handle its own children! So, if I were bypassing the normal storyboard loading process by the system by removing references to it in the info.plist file, I would at most instantiate the rootViewController using instantiateViewControllerWithIdentifier:
, and possibly its root if it is a container, like a UINavigationController. What you want to avoid is instantiating view controllers that have already been instantiated by the storyboard. This is a problem I see a lot. In short, I disagree with the accepted answer. It is incorrect unless the posters means to remove loading of the storyboard from the info.plist since you will have loaded 2 storyboards otherwise, which makes no sense. It's probably not a memory leak because the system initialized the root scene and assigned it to the window, but then you came along and instantiated it again and assigned it again. Your app is off to a pretty bad start!