iOS 9 中未调用 awakeFromNib
Posted
技术标签:
【中文标题】iOS 9 中未调用 awakeFromNib【英文标题】:awakeFromNib Not Called in iOS 9 【发布时间】:2015-09-25 19:11:56 【问题描述】:我遇到了一个有趣的问题。我有一个视图控制器:
LoginViewController *viewController = [LoginViewController alloc] init];
在initWithNibName:bundle:
和awakeFromNib
方法中,我有一些初始化代码。 LoginViewController 有一个名为 LoginViewController.xib 的 .xib 文件。
但是,针对 ios 9 构建,这些方法永远不会被调用,代码也永远不会运行。但是,除非我像这样初始化我的LoginViewController
:
LoginViewController *viewController = [LoginViewController alloc] initWithNibName:nil bundle:nil];
然后代码运行,它工作得非常好。似乎正在加载 .xib 文件,但从未调用过 initWithNibName:bundle:
和 awakeFromNib
。
有谁知道为什么在 iOS 9 中 awakeFromNib
在存在相应的 .xib 时默认不会被调用?这个问题在 iOS 8 中不存在(awakeFromNib
被调用,即使我只是使用init
来初始化我的视图控制器)。
【问题讨论】:
嗯,这对我来说是合乎逻辑的。没有NIB,所以它不会调用awakeFromNib
。
@FreeNickname 抱歉,我忘了说 LoginViewController 确实有一个 .xib 文件。我已经编辑了问题以反映这一点。
xib叫什么?
@Fogmeister .xib 同名 LoginViewController (LoginViewController.xib)。
好吧,你将不得不提供更多的代码或其他东西。您说它与 initWithNibNamed 一起使用...但是您提供的 nib 名称是 nil。这将迫使它不使用笔尖。所以如果你使用它,awakeFromNjb 绝对不应该工作。能不能再解释一下。 init 和 awakeFromNib 中的哪一个在工作/不工作,什么时候工作?
【参考方案1】:
iOS 9 Release Notes 中描述了对视图控制器 nib 加载行为的更改:
如果用 nil nibName 值初始化,UIViewController.nibName 总是寻找与视图控制器的类具有相似名称的 nib,如果 loadView 没有被覆盖,则默认为该值。 在 iOS 9 之前,用 Swift 编写的 UIViewController 的子类需要它们对应的 nib 文件名包含模块前缀。
为了提高重构时的灵活性,您可以在 iOS 9 中运行的代码中从 nib 文件名中省略模块名称。 UIViewController.nibName 仍然更喜欢包含模块前缀的名称,但回退到不合格的名称如果未找到具有完全限定名称的 nib。
另外,class documentation for UIViewController 声明:
如果您为 nibName 参数指定 nil 并且不覆盖 loadView 方法,则视图控制器会按照 nibName 属性中的说明搜索 nib 文件。
如果您在-initWithNibNamed:bundle:
中执行初始化,最好在-initWithCoder:
和/或-loadView
中执行初始化(取决于您在做什么)。 -awakeFromNib
仍然适用于通常应该去那里的东西。
从您的问题看来:
- 当使用-init
实例化视图控制器子类时,不会调用-initWithNibNamed:bundle:
和awakeFromNib
。
- -initWithNibNamed:bundle:
和 awakeFromNib
正在 当视图控制器子类被 -initWithNibNamed:bundle:
实例化时被调用。
这有点奇怪。 -initWithNibNamed:bundle:
是指定的初始化程序,因此 -init
应该使用 nil 参数调用它以触发上述行为。在 iOS 9 上使用Hopper 快速反汇编 UIKit 表明情况仍然如此。
如果您覆盖 -loadView
-initWithNibName:bundle:
将不会尝试为您加载笔尖 - 通过覆盖 -loadView
您选择自己这样做。如果您要覆盖 -loadView
(即使您调用 super),请将其删除,笔尖应该会加载。 -awakeFromNib
不会被调用,因为视图控制器是 nib 的所有者 - 只有孩子才能获得该方法调用。如果它是情节提要的一部分,它将被调用。但是,-awakeAfterUsingCoder:
将被调用,并且可能是一个更好的地方来完成您在 -awakeFromNib
中尝试的工作。
我将您的问题简化为一个简单的测试用例,并在 iOS 9 和 iOS 8.4 SDK 上确认了这种行为。
【讨论】:
【参考方案2】:我遇到了同样的问题。出于某种原因,我的方法 awakeFromNib -awakeFromNib
没有被调用。我知道这不是一个好习惯,但如果您注意自己的代码,您可以使用NSNotificationCenter
来解决这个问题。
【讨论】:
以上是关于iOS 9 中未调用 awakeFromNib的主要内容,如果未能解决你的问题,请参考以下文章
在 iOS 9 中未调用 updateSearchResultsForSearchController
在 iOS 11 和 Xcode 9.1 中未调用 CLLocationManager 的 didUpdateLocations 委托 [重复]
“viewWillTransitionToSize:”当视图控制器以模态方式呈现时在 iOS 9 中未调用
准备(用于 segue:UIStoryboardSegue,发件人:任何?)在 iOS 11 上的 Xcode 9 b6 中未调用
在 iOS 15 中未分配 Alamofire 4.9.1 sessionManager.delegate.sessionDidReceiveChallenge