我的Cocoa应用程序出现问题。我正在使用我的app委托作为控制器,并在NIB文件中打开一个窗口。单击工具栏按钮将打开另一个NIB的另一个窗口。单击第二个窗口上的save将调用app delegate / controller上的方法。这一切都很好。
奇怪的是,我无法弄清楚当我单击工具栏按钮时,应用程序委托指向一个内存位置,在第二个窗口上单击保存后指向不同的内存位置。这就好像正在创建第二个应用程序委托/控制器,虽然单步执行代码并没有给出任何关于这种情况的指示。
有没有更好的方法来构建这种类型的应用程序?知道我哪里出错了吗?
答案 0 :(得分:2)
听起来你正在窗口的nib文件中创建AppController
类的第二个实例。您不能这样做,当nib在运行时取消存档时,将实例化nib文件中对象的每个实例。这意味着如果AppController
中有MainMenu.xib
个实例,而MyWindow.xib
文件中有AppController
个实例,则First Responder
对象将被分配并初始化两次。
通常,处理此问题的方法是使用响应程序链。在您的Window笔尖中,您将-respondsToSelector:
指定为您的操作的目标。这意味着当调用action方法时,如果应用程序通过调用NSApplication
方法并传入操作选择器来响应方法,那么应用程序将询问当前关注的视图/控件(具有第一响应者状态的视图/控件)
如果第一个响应者没有响应该方法,则消息沿着响应者链向上移动,直到找到响应该方法的对象。如果没有对象响应该方法,NSBeep()
实例将对其进行处理并调用NSApplication
。
在将方法发送到AppController
实例之前,会询问应用程序委托是否响应选择。在这种情况下,如果您的[[NSApp delegate] yourMethod]
对象被设置为应用程序委托,它将从窗口nib中的对象接收作为操作发送的消息。
如果不够清楚,则值得阅读Event Handling guide
您没有拥有来使用响应者链。您可以通过调用NSWindowController
在应用程序委托上调用方法。您还可以通过将其作为实例变量添加到加载nib并在创建时设置它的- (id)initWithAppController:(id)aController
{
self=[super initWithWindowNibName:@"YourWindowNibName"];
if(self)
{
appController = [aController retain];
}
return self;
}
对象来存储对app控制器的引用,如下所示:
{{1}}
您的窗口控制器可以直接调用AppController的方法。