根据NSObject UIKit Additions Reference,出口变量应在awakeFromNib
调用时设置(强调所有我的):
nib 加载基础架构向从 nib 存档重新创建的每个对象发送 awakeFromNib 消息,但前提是存档中的所有对象都已加载和初始化。当一个对象收到一个 awakeFromNib 消息时,它保证已经建立了它的所有出口和动作连接。
...
重要提示:由于无法保证从档案中实例化对象的顺序,因此您的初始化方法不应向层次结构中的其他对象发送消息。可以从 awakeFromNib 方法中安全地向其他对象发送消息。
通常,您为需要在设计时无法完成的额外设置的对象实现 awakeFromNib。例如,您可以使用此方法自定义任何控件的默认配置,以匹配用户首选项或其他控件中的值。您也可以使用它来将各个控件恢复到应用程序的某个先前状态。
但是,这与我的测试不匹配,至少使用 Storyboards。以下测试的结果似乎与文档相矛盾:
- 在 Xcode 中创建一个新的单一视图应用程序。
- 将第二个 ViewController 拖到情节提要上。
- 给第一个 ViewController 一个按钮,并从该按钮创建一个模态 segue 以显示第二个 ViewController。
- 为第二个 ViewController 创建一个 ViewController 类文件。
- 在情节提要的第二个 ViewController 上创建一个标签,并创建一个
someLabel
从它调用到相应 ViewController 类的出口。 - 将以下
awakeFromNib
实现添加到第二个 ViewController:
.
- (void) awakeFromNib {
[super awakeFromNib];
if (self.someLabel == nil) {
NSLog(@"someLabel property is nil");
}
else {
NSLog(@"someLabel property is not nil");
}
if (_someLabel == nil) {
NSLog(@"_someLabel is nil");
}
else {
NSLog(@"_someLabel is not nil");
}
}
- 在模拟器中运行应用程序并单击按钮。
当我这样做时,我观察到以下记录:
2013-07-01 09:24:35.755 test[498:c07] someLabel property is nil
2013-07-01 09:24:35.758 test[498:c07] _someLabel is nil
由于这种行为,当我需要我的 ViewControllers 具有一些涉及其插座的初始化逻辑时,我需要使用类似于此处答案中提出的黑客攻击,以便能够使用插座。如果我正确理解了文档,那么我被迫使用这个 hack 的事实是 UIKit 行为中的一个错误,我应该能够将该初始化放入awakeFromNib
并简单地使用插座而无需任何 hack。
不过,我在互联网上找不到任何其他提及此问题的内容,考虑到(对我而言)这是一项非常重要的功能,这似乎很奇怪。我也从未使用过实际的 nib 文件,只有故事板,所以我对此缺乏一些看法,而且关于这些东西的文档非常冗长和困难,以至于作为 iOS 的新手,我不相信我已经理解正确。这是一个真正的 UIKit 错误,还是我以某种方式误解了文档 - 也许这种方法甚至不打算与情节提要一起使用?