通常,系统应使用情节提要处理视图控制器实例化。您想要的是通过获取对的引用来遍历viewController层次结构,self.window.rootViewController
而不是初始化视图控制器,如果正确设置了故事板,则应该已经正确初始化了。
因此,假设您rootViewController
是一个UINavigationController,然后要将某些内容发送到其顶部视图控制器,则可以在AppDelegate的控件中执行以下操作didFinishLaunchingWithOptions
:
UINavigationController *nav = (UINavigationController *) self.window.rootViewController;
MyViewController *myVC = (MyViewController *)nav.topViewController;
myVC.data = self.data;
在Swift中,如果非常相似:
let nav = self.window.rootViewController as! UINavigationController;
let myVC = nav.topViewController as! MyViewController
myVc.data = self.data
除非您要绕过加载故事板的正常方式并自己加载整个故事板,否则您实际上不应该使用应用程序委托中的故事板ID初始化视图控制器。如果您必须通过AppDelegate初始化场景,则很可能在做一些错误的事情。我的意思是想象一下,由于某种原因,您想将数据发送到堆栈中的视图控制器,AppDelegate不应进入视图控制器堆栈以设置数据。那不是它的事。它的业务是rootViewController。让rootViewController处理自己的孩子!因此,如果我通过在info.plist文件中删除对其进行的引用来绕过系统正常的情节提要加载过程,则最多使用以下方法实例化rootViewController:instantiateViewControllerWithIdentifier:
,如果是容器,例如UINavigationController,则可能是其根。您要避免的是实例化已由情节提要实例化的视图控制器。我看到的这个问题很多。简而言之,我不同意接受的答案。除非张贴者打算从info.plist中删除故事板的加载,否则这是不正确的,因为否则您将加载2个故事板,这是没有意义的。可能不是内存泄漏,因为系统初始化了根场景并将其分配给窗口,但是随后您又来实例化它并再次分配它。您的应用程序开局非常糟糕!