以编程方式加载 nib2 时,来自 nib1 的 awakeFromNib 被调用

Posted

技术标签:

【中文标题】以编程方式加载 nib2 时,来自 nib1 的 awakeFromNib 被调用【英文标题】:awakeFromNib from nib1 got called when programmatically load nib2 【发布时间】:2011-05-18 20:32:53 【问题描述】:

当我使用以下语法从 nib1 加载 nib2 时,我当前的 nib (nib1) 中的 awakeFromNib 方法再次被调用。 (但不是 initWithFrame 方法)即使 nib2 已打开并正确获得焦点。我不希望再次执行来自 nib1 的 awakeFromNib。我错过了什么?

[NSBundle loadNibNamed:@"iQueryWindow" owner:self];

更多信息:iQueryWindow.xib 有一个 NSView 的 iQueryView.h 和 iQueryView.m 子类与之关联,以创建带有按钮、文本字段等的窗口视图。事件顺序如下所示:我从 nib1 中单击了一个按钮看,它的 clicked 事件只有上面一行代码来打开 nib2 的窗口。 Nib2 的窗口以所有初始化打开,包括其 (nib2) 自己的 inintWithFrame 和 awakeFromNib 方法。之后我可以观察到 nib1 的窗口由于调用了它自己的 awakeFromNib 而发生了变化(我也可以在 NSlog 语句的帮助下通过控制台观察到这一点)。 (nib2 的窗口显示在 nib1 的顶部。)nib2 上有一个按钮可以关闭 nib2:[self.window close]。

【问题讨论】:

你能显示更多代码吗?您提供的信息不足以诊断问题。 由于您拥有当前视图作为所有者,它将收到 awakeFromNib。加载后你会做什么? @joshpaul:在 nib1 上,我点击了一个按钮。 button_clicked 事件只有上面一行代码来打开 nib2。 Nib1 的窗口还在屏幕上。 Nib2 的窗口仅显示在 nib1 的顶部。我可以看出,来自 nib1 的 awakeFromNib 被调用,因为 nib1 屏幕上的信息发生了变化,并且从控制台监视器中查看。调用 open nib2 后的事件顺序如下: Nib2 打开,然后调用来自 nib2 的 awakeFromNib。 @Deepak:nib2 打开后,我可以将它用作普通窗口...访问所有按钮等并执行预期任务。 nib2 上有一个按钮,单击该按钮将关闭 nib2。我又回到了 nib1。 ` 【参考方案1】:

-awakeFromNib 被发送到 nib 文件中的所有对象,包括文件的所有者。如果您有一个从 nib 文件加载的对象,并使该对象成为另一个 nib 文件的所有者,它将收到两次-awakeFromNib。这是设计使然。

虽然你可以有一个 ivar 来管理你的类在从 nib 唤醒方面的状态,但请考虑使用NSViewController(或NSWindowController)的子类;目前还不清楚 nib2 是否有视图或窗口作为其***对象之一)作为辅助 nib 文件的文件所有者。

【讨论】:

1. nib2 有一个窗口(NSWindow)作为它的顶层对象。 NSView 的 iQueryView 子类位于此窗口内。 2. 我没有设置 nib2 的文件所有者 - 没有。 @user [NSBundle loadNibNamed:@"iQueryWindow" owner:self]; 表示所有者是self,我假设它是从 nib1 加载的对象。 我使用 NSWindowController 而不是 NSBundle 来解决这个问题。【参考方案2】:

根据 Bavarious 的建议,我使用 NSWindowController 而不是 NSBundle 来解决此问题。代码如下:

NSWindowController *iQWController = [[NSWindowController alloc] initWithWindowNibName:@"iQueryWindow"];
[iQWController showWindow:sender];

【讨论】:

以上是关于以编程方式加载 nib2 时,来自 nib1 的 awakeFromNib 被调用的主要内容,如果未能解决你的问题,请参考以下文章

防止在表格视图Swift中重用自定义单元格

当我以编程方式从情节提要加载窗口时,为啥在 NSView 中未调用 drawRect?

以编程方式加载时无法从类函数内部访问 jQuery UI

Swift - StackView 和添加约束,以编程方式添加视图到堆栈 - 加载后调整单元格高度?

在 UITableView 重新加载时以编程方式打开/关闭 UITextField 的 inputView

initWithNibName 方法,我可以只使用笔尖名称的前几个字符吗