ios9中没有调用awakeFromNib



我遇到了一个有趣的问题。我有一个视图控制器:

LoginViewController *viewController = [LoginViewController alloc] init];

initWithNibName:bundle:awakeFromNib方法中,我有一些初始化代码。LoginViewController有一个.xib文件,名为LoginViewController.xib.

然而,针对iOS 9构建,这些方法永远不会被调用,代码永远不会运行。但是,除非我像这样初始化我的LoginViewController:

LoginViewController *viewController = [LoginViewController alloc] initWithNibName:nil bundle:nil];

然后运行代码,它工作得很好。看起来正在加载.xib文件,但是从未调用initWithNibName:bundle:awakeFromNib

有谁知道为什么在iOS 9 awakeFromNib没有得到调用默认情况下,当相应的。xib存在?这个问题在iOS 8中不存在(即使我只是使用init来初始化我的视图控制器,awakeFromNib也会被调用)。

视图控制器nib加载行为的变化在iOS 9发布说明中有描述:

如果初始化为nil nibName值,UIViewController。nibName总是寻找一个与视图控制器类名称相似的nib,如果loadView没有被覆盖,nibName默认为那个值。在ios9之前,用Swift编写的UIViewController的子类会要求它们对应的nib文件名包含模块前缀。

为了提高重构时的灵活性,你可以在iOS 9中运行的代码中省略nib文件名中的模块名。ui。nibName仍然倾向于使用包含模块前缀的名称,但如果没有找到具有完全限定名称的nib,则会退回到非限定名称。

另外,UIViewController的类文档声明:

如果你为nibName参数指定nil,并且你没有覆盖loadView方法,视图控制器将按照nibName属性中的描述搜索nib文件。

如果你在-initWithNibNamed:bundle:中执行初始化,最好在-initWithCoder:和/或-loadView中执行初始化(取决于你在做什么)。-awakeFromNib仍然适用于通常应该放在那里的东西。

从你的问题看来,似乎:当视图控制器子类用-init实例化时,-initWithNibNamed:bundle:awakeFromNib不会被调用。- -initWithNibNamed:bundle:awakeFromNib 在视图控制器子类用-initWithNibNamed:bundle:实例化时被调用。

这有点奇怪。-initWithNibNamed:bundle:是指定的初始化器,因此-init应该带nil参数调用它来触发上面描述的行为。使用Hopper在iOS 9上快速反汇编UIKit,可以看出情况仍然如此。

如果你覆盖-loadView, -initWithNibName:bundle:将不会尝试为你加载笔尖——通过覆盖-loadView,你选择自己去做。如果你重写-loadView(即使你调用super),删除它,nib应该加载。-awakeFromNib不会被调用,因为视图控制器是nib的所有者-只有子节点会得到那个方法调用。如果它是故事板的一部分,它就会被调用。然而,-awakeAfterUsingCoder:将被调用,并且可能是做您在-awakeFromNib中尝试的工作的更好的地方。

我将你的问题简化为一个简单的测试用例,并在iOS 9和iOS 8.4 sdk中确认了这种行为。

我也遇到了同样的问题。由于某种原因,我的方法awakeFromNib -awakeFromNib没有被调用。我知道这不是一个好的做法,但如果你关心你的代码,你可以使用NSNotificationCenter来解决这个问题。

相关内容

  • 没有找到相关文章

最新更新