7

所以我花了一些时间检查 CocoaDev,阅读 NSMenuItems 上的 Cocoa 文档,并在 Interface Builder 中进行了一些测试。

在我的应用程序中,我有一个在 Interface Builder 中设计的应用程序菜单([NSApp mainMenu])。我看到了三种可能的路径:

  1. 将我的动作响应者放在 NSApplicationDelegate 中。这对我来说似乎很奇怪,部分原因是它位于食物链的上游,部分原因是它似乎被固定住了。

  2. 创建一个子视图来监听各种 NSMenuItem 操作消息。这看起来很有用,但看起来为了让它在响应者链中,可能有一些我无法理解的魔法。

  3. 创建一个监听特定应用程序菜单内容的 NSObject,将其放入 xib 中,然后将其连接起来。在我看来,这似乎是目前最好的解决方案,因为我可以隔离东西,而不是依赖响应者链来到达特定对象。但我想知道,当我的应用程序达到足够复杂的水平时,这是否可能是一个问题,因为它篡夺了响应者链,这可能是出于易用性之外的原因。

对不起,很长的问题。有首选方法吗?谢谢!

4

2 回答 2

7

这实际上取决于您的应用程序的体系结构。作为一般规则,在任何有意义的地方实施行动。行动消息的响应者链可以在这方面为您提供帮助。

如果您的应用程序不是基于文档的,则操作消息的响应者链如下所示:

  1. 无论哪个响应者是第一响应者
  2. 查看层次结构
  3. 窗户
  4. 窗口控制器
  5. 窗口委托
  6. NSApp
  7. 应用程序委托

如果它们对整个应用程序真正是全局的,我只会在应用程序委托中使用它们。否则,如果它们对特定窗口有意义,我将它们放在窗口控制器(通常也是窗口委托)中,或者如果它们对特定视图有意义,则将它们放在视图控制器中。

值得一提的是,视图控制器(的子类NSViewController)不会自动插入响应者链中。在将相应的视图添加到超级视图后,我手动执行此操作。例如,在NSViewController子类中:

NSResponder *nextResponder = [[self view] nextResponder];
[[self view] setNextResponder:self];
[self setNextResponder:nextResponder];

这会在视图和原始视图的下一个响应者之间的响应者链中插入self(的子类的一个实例)。NSViewController

请注意,您的第三种方法本质上没有任何问题,即为(一部分)操作消息设置特定目标。响应者链的存在是为了让不同的对象有机会处理动作消息,因为某些动作可能是上下文相关的。例如,“文件”菜单下的操作通常应用于当前主窗口的窗口,因此没有特定目标而使用响应程序链是有意义的。另一方面,ApplicationName 菜单下的操作是真正全局的——它们不需要通过响应者链,因此您可以将它们连接到特定目标。

于 2011-05-06T22:02:10.337 回答
0

我通常只IBActions在应用程序控制器(NSApp委托)中公开,并将菜单项连接到这些操作。这是一种非常标准的做事方式。如果您有很多菜单项,您还可以将功能分解为一个或多个连接到应用程序控制器的控制器,并将菜单项连接到它们。

于 2011-05-06T21:26:43.043 回答