从Interface Builder连接NSMenuItems的最佳方法?

Chr*_*ill 7 objective-c first-responder nsmenuitem

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

在我的应用程序中,我有一个在Interface Builder中设计的应用程序菜单([NSApp mainMenu]).我看到三条潜在的路径:

  1. 将我的操作响应程序放在NSApplicationDelegate中.这对我来说似乎很奇怪,部分原因是因为它远远超过了食物链,部分原因是因为它看起来像是狂奔.

  2. 创建一个可以侦听各种NSMenuItem操作消息的子视图.这似乎很有用,但看起来为了让它在响应链中可能会有一些我无法弄清楚的魔法.

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

很抱歉这个问题很长.有首选方法吗?谢谢!

小智 7

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

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

  1. 无论哪个响应者是第一响应者
  2. 查看层次结构
  3. 窗口
  4. 窗口控制器
  5. 窗口代表
  6. NSApp
  7. 申请代表

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

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

NSResponder *nextResponder = [[self view] nextResponder];
[[self view] setNextResponder:self];
[self setNextResponder:nextResponder];
Run Code Online (Sandbox Code Playgroud)

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

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