2011-05-06 60 views
6

所以我花了一些时间检查CocoaDev,阅读NSMenuItems上的Cocoa文档,并在Interface Builder中做一些测试。从Interface Builder连接NSMenuItems的最佳方法是什么?

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

  1. 将我的动作响应者放在NSApplicationDelegate中。这对我来说似乎很陌生,部分原因是它距离食物链很远,部分原因是它看起来狂奔。

  2. 创建一个可以侦听各种NSMenuItem动作消息的子视图。这似乎很有用,但它看起来像为了在响应者链中可能有一些我无法想象的魔法。

  3. 创建一个NSObject,它侦听特定的应用程序菜单的东西,把它放在xib中,然后连线。这对我来说似乎是目前最好的解决方案,因为我可以分离内容,而不依赖于响应者链来达到特定对象。但是,我想知道,当我的应用程序达到足够的复杂程度时,这可能是一个问题,因为它篡夺了响应者链,这可能是因为使用方便以外的原因。

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

回答

6

它确实取决于您的应用程序的体系结构。作为一般规则,在有意义的地方实施行动。行动信息的响应者链在这方面可以帮助你。

如果您的应用程序不是基于文档的,采取行动的消息响应链是这样的:

  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菜单下的操作确实是全局的 - 它们不需要通过响应者链,因此您可以将它们连接到特定目标。

+0

谢谢Bavarious!我忽略了setNextResponder功能,这使得事情看起来不如以前那么灵活。既然你和mipadi都提到可以把这些东西放到应用程序委托中,那么我就会坚持我的全局东西。 – 2011-05-08 04:22:12

+0

+1感谢这个信息..经过长时间的搜索和努力,我找到了这个答案 – 2013-06-19 11:15:32

+0

当我尝试实现第三种方法时,我的menuItem是灰色的。为什么会发生? – 2016-05-04 20:40:15

0

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

+0

谢谢米帕迪。你提到将控制器分成子控制器让我想到了! – 2011-05-08 04:25:19

相关问题