初始化之前调用viewDidLoad?

24

我遇到了一个奇怪的情况。在我的控制器中,viewDidLoad被调用之前先调用了init。这背后是否有任何技术原因?

6个回答

55

viewDidLoad 方法在 init 方法中访问 self.view 时被调用(因为此时 self.view 尚未从 nib 中加载,所以该过程似乎很快并且不会返回 nil)。


7
谢谢。在初始化函数中的self.view是我的一个大问题。 - Almas Adilbek
1
谢谢,将任何self.view的活动移动到viewDidLoad中,并将所有在指定的初始化器中所需的属性从self.property更改为_property。问题都解决了。 - Jonauz
晚来的评论,我遇到了同样的问题,但是我很困惑,为什么会这样?它只是绕过了构造函数吗? - David Pullar
1
@DavidPullar 它不是绕过它,而是在第一次使用时加载“view”(调用“viewDidLoad”)。这就像从“init”内部手动调用“viewDidLoad”。 - alex-i

25

我知道这篇文章有点老了,但我还是想在任何地方发表我的观点,因为我认为它可能会帮助某些人。

好吧,我也遇到过同样的情况。我以为viewDidLoad方法是在我的视图控制器类的init方法之前被调用的。但实际上发生的不是这样的:流程从init方法开始,但当调用[super init*]时跳转到viewDidLoad方法,所以我的日志消息在viewDidLoad方法中首先显示而不是在我的自定义初始化之前。

我想就是这样。我希望这能节省一些时间给某些人。

[对我的英语表示抱歉]


很棒的观察! - Roi Mulia
2
这对我很有帮助。谢谢,Ricard!我的应用程序调用了我的自定义初始化程序(它调用了super.init),这导致它在离开该自定义初始化程序之前调用viewDidLoad。最终,我在我的自定义初始化程序的末尾调用了super.init,以便在调用viewDidLoad之前设置好了我想要设置的所有内容。 - Brian Sachetta

12

关于UITabBarController的注意事项:

我不知道是哪种UIViewController导致了这个问题,但我遇到了与UITabBarController类似的情况。 我认为这可能会对面临UITabBarController问题的人有所帮助。
据我所知,除了UITabBarController及其子类之外,所有viewControllers都会在viewDidLoad之前调用init方法。
正如Andrew声称的那样(传送门)UITabBarController[super init]方法内部调用loadView,这将导致调用viewDidLoad方法。因此,在init完成其任务之前,viewDidLoad方法将被调用。
如果您需要在viewDidLoad方法中进行一些设置,您应该在调用[super init]之后的init方法中进行。


我一整天都在与我的UITabBarController子类进行斗争,不明白为什么有些变量是nil,即使我在viewDidLoad被调用之前设置了它们,而将UITabBarController更改为UIViewController则可以解决所有问题...像往常一样,苹果的文档缺乏任何副作用或特殊情况的说明... - Moumou

3
当你从代码中初始化一个UIViewController时,你需要使用-initWithNibName:bundle:方法;而当它从XIB文件中初始化时,XIB加载代码将调用-initWithCoder:方法。这两个方法中只会被调用其中一个,并且它们一定会在-viewDidLoad方法之前被调用。
除非你自己调用(但你真的不应该这么做),否则-viewDidLoad绝对不可能首先被调用。

0

不,viewDidLoad消息总是在init之后调用。

你确定init被调用了吗?UIViewController有几个init方法,也许另一个被调用了,让你产生了不同的想法。

如果需要更多信息,请粘贴viewDidLoad和所有init方法的代码,并告诉我们它是如何加载的(即通过代码还是从nib文件中)。


1
是的,init 方法确实被调用了,但是是在 viewDidLoad 方法之后。对于这个特定的 UIViewController,只需要分配和初始化它,并将该控制器设置为 UITabBarController 的视图控制器,然后呈现 tabbarController,这里有什么问题吗? - Sandeep Kumar
Init在viewDidLoad之前运行,除非你犯了非常不可能的错误。你可能缺少另一个init或者得出了错误的结论。是什么让你认为init在viewDidLoad之后被调用了呢?你有检查过这是同一个对象吗?再次强调,没有代码就无法检查。 - Eiko

-1
如果您的ViewController是从主nib文件加载的,则最有可能调用initWithCoder来初始化控制器。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接