3

我是 MacRuby 和 Cocoa 的完整 n00b,所以在回答时请记住这一点 - 我需要很多细节和解释。:)

我已经建立了一个简单的项目,其中有 2 个窗口,这两个窗口都是用 Interface Builder 构建的。第一个窗口是使用表格视图的简单帐户列表。它在表格下方有一个“+”按钮。当我单击 + 按钮时,我想显示一个“添加新帐户”窗口。

我还有一个AccountsController < NSWindowController和一个AddNewAccountController < NSWindowController类,设置为这些窗口的代表,连接了适当的按钮单击方法,以及引用所需窗口的插座。

当我单击“帐户”窗口中的“+”按钮时,我会触发以下代码:

    @add_account.center
    @add_account.display
    @add_account.makeKeyAndOrderFront(nil)
    @add_account.orderFrontRegardless

这在我第一次单击 + 按钮时效果很好。一切都出现了,我可以输入我的数据并将其绑定到我的模型。但是,当我关闭添加新帐户表单时,事情开始变得糟糕。

如果我将添加新帐户窗口设置为关闭时释放,那么我第二次单击 + 按钮时,该窗口仍会弹出但它被冻结。我无法单击任何按钮、输入任何数据,甚至无法关闭表单。我认为这是因为表单的代码已经发布,所以没有消息循环处理表单......但我对此并不完全确定。

如果我将添加新帐户窗口设置为关闭时不释放,那么我第二次单击 + 按钮时,窗口显示正常并且可用 - 但它仍然包含我之前输入的所有数据......仍然绑定到我以前的 Account 类实例。

我究竟做错了什么?当我单击 Accounts 表单上的 + 按钮时,创建 Add New Account 表单的新实例、创建新 Account 模型、将该模型绑定到表单并显示表单的正确方法是什么?

...这一切都在 OSX 10.6.6、64 位和 XCode 3.2.4 上完成

4

1 回答 1

1

问题是它不会每次都创建窗口。关闭时释放是一个令人讨厌的选项,通常仅在您知道窗口关闭时也释放窗口控制器时才使用。(请注意,我从未使用过 MacRuby,所以我将在 Obj-C 中提供代码,因为我知道它是正确的,希望您可以转换它。我将假设 GC 已打开,因为它应该与 MacRuby 一起使用)。

现在有两种方法可以做到这一点。我不完全确定您的 NIB/类是如何设置的,因为它可能是两种方式之一。

--

解决它的第一种方法是使用您用来引用表单元素的插座,以便在您再次显示窗口时将它们空白,例如 [myTextField setStringValue:@""]。如果您使用的是可可绑定,那么它会有点棘手,但基本上您必须确保绑定的对象是空白的。如果您是 Cocoa 的新手,我建议您不要使用绑定。

--

第二种方法是使 AddNewAccountController 类成为 NSWindowController 的子类。当您按下 + 按钮时,您将创建它的一个新实例并显示它(记住将它存储在 ivar 中)。最好的方法是这样:

if (!addAccountController) {
    addAccountController = [[AddNewAccountController alloc] initWithWindowNibName:@"AddNewAccountController"];
    [[addAccountController window] setDelegate:self];
}
[addAccountController showWindow:self];

如果窗口已经可见,这可以防止创建新实例。然后您需要实现委托:

- (void)windowWillClose:(NSNotification *)notification {
    //If you don't create the account in the AddNewAccountController then do it here
    addAccountController = nil;
}

显然,您需要将窗口移动到名为“AddNewAccountController”的单独 NIB。在此 NIB 中,确保将文件所有者的类设置为 AddNewAccountController,然后将文件所有者的窗口出口连接到窗口。

当所有这些都设置好后,你每次都会得到一个新的控制器/窗口。它还具有将笔尖和控制器分成更集中的单元的好处。

--

最后一件事。虽然可以在窗口中执行此类操作,但您可能希望最终通过工作表查看执行此操作,因为这样可以防止添加帐户窗口隐藏在其他窗口后面的可能性。

于 2011-01-30T15:24:45.750 回答