【问题标题】:Problem with multiple window/NIB cocoa application多窗口/NIB 可可应用程序的问题
【发布时间】:2010-02-04 03:18:05
【问题描述】:

我的 Cocoa 应用程序有问题。我正在使用我的应用程序委托作为控制器,并在 NIB 文件中打开一个窗口。单击工具栏按钮会从另一个 NIB 中打开另一个窗口。单击第二个窗口上的保存会调用应用程序委托/控制器上的方法。这一切都很好。

奇怪的是,我不知道当我单击工具栏按钮时应用程序委托指向一个内存位置,而在第二个窗口上单击保存后又指向另一个内存位置。就好像正在创建第二个应用程序委托/控制器,尽管单步执行代码并没有给我任何迹象表明这种情况正在发生。

有没有更好的方法来构建这种类型的应用程序?知道我哪里出错了吗?

【问题讨论】:

    标签: cocoa interface-builder cocoa-design-patterns


    【解决方案1】:

    听起来您正在窗口的 nib 文件中创建 AppController 类的第二个实例。您不能这样做,当 nib 在运行时取消归档时,nib 文件中的每个对象实例都将被实例化。这意味着如果您在MainMenu.xib 中有一个AppController 实例,并且还有一个MyWindow.xib 文件,那么AppController 对象将被分配和初始化两次。

    通常处理此问题的方式是使用响应者链。在您的 Window nib 中,您将 First Responder 指定为您的操作目标。这意味着当调用动作方法时,应用程序将通过调用-respondsToSelector: 方法并传入动作选择器来询问当前聚焦的视图/控件(具有第一响应者状态的视图/控件)是否响应该方法。

    如果第一个响应者没有响应该方法,则消息将沿响应者链向上传播,直到找到确实响应该方法的对象。如果没有对象响应该方法,NSApplication 实例会处理它并调用NSBeep()

    就在将方法发送到NSApplication 实例之前,会询问应用程序委托是否响应选择。在这种情况下,如果您的 AppController 对象被设置为应用程序委托,它将在窗口 nib 中接收您的对象作为操作发送的消息。

    如果这还不够清楚,值得阅读Event Handling guide

    你没有使用响应者链。您可以通过调用[[NSApp delegate] yourMethod] 来调用应用程序委托上的方法。您还可以通过将其作为实例变量添加到加载 nib 并在创建时设置它的 NSWindowController 对象来存储对应用控制器的引用,如下所示:

    - (id)initWithAppController:(id)aController
    {
        self=[super initWithWindowNibName:@"YourWindowNibName"];
        if(self)
        {
            appController = [aController retain];
        }
        return self;
    }
    

    然后您的窗口控制器可以直接调用您的 AppController 的方法。

    【讨论】:

    • 确实这就是我正在做的。我会花一些时间阅读推荐的指南;我不太明白如何使用 FirstResponder 对象及其与我的代码的连接。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多