1

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

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

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

4

1 回答 1

2

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

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

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

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

如果这还不够清楚,值得阅读事件处理指南

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

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

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

于 2010-02-04T09:45:56.067 回答