所以我花了一些时间查看CocoaDev,阅读NSMenuItems上的Cocoa文档,并在Interface Builder中进行一些测试。
在我的应用程序中,我有一个在Interface Builder中设计的应用程序菜单([NSApp mainMenu])。我看到了三条潜在的路径:
将我的操作响应程序放在NSApplicationDelegate中。这对我来说似乎很奇怪,部分原因是因为它远远超过了食物链,部分原因是因为它看起来像是狂奔。
创建一个可以侦听各种NSMenuItem操作消息的子视图。这似乎很有用,但看起来为了让它在响应链中可能会有一些我无法弄清楚的魔法。
创建一个NSObject,用于侦听特定的应用程序菜单内容,将其放入xib中,然后将其连接起来。这在我看来是目前最好的解决方案,因为我可以隔离东西,而不依赖于响应者链来达到特定对象。但是我想知道,当我的应用程序达到足够高的复杂程度时,这可能是一个问题,因为它篡夺了响应者链,这可能是一个超出易用性的原因。
很抱歉这个问题很长。有首选方法吗? 谢谢!
答案 0 :(得分:7)
这实际上取决于应用程序的体系结构。作为一般规则,在任何有意义的地方实施行动。在这方面,响应者行动消息链可以帮助您。
如果您的应用程序不是基于文档的,则操作消息的响应者链如下所示:
NSApp
我只在应用程序委托中使用操作,如果它们对整个应用程序来说真的是全局的。否则,我将它们放在窗口控制器(通常也是窗口委托)中,如果它们对特定窗口有意义,或者视图控制器对特定视图有意义。
值得一提的是,视图控制器(NSViewController
的子类)不会自动插入响应器链中。我将相应的视图添加到superview后手动执行此操作。例如,在NSViewController
子类中:
NSResponder *nextResponder = [[self view] nextResponder];
[[self view] setNextResponder:self];
[self setNextResponder:nextResponder];
这会在视图和原始视图的下一个响应者之间的响应者链中插入self
(NSViewController
的子类的实例)。
请注意,您的第三种方法没有任何内在错误,即为(一部分)动作消息设定特定目标。响应者链的存在是为了让不同的对象有机会处理动作消息,因为某些动作可能与上下文有关。例如,“文件”菜单下的操作通常应用于当前主窗口的窗口,因此没有特定目标并使用响应程序链是有意义的。另一方面,ApplicationName菜单下的操作是真正全局的 - 它们不需要通过响应者链,因此您可以将它们连接到特定目标。
答案 1 :(得分:0)
我通常只是在app控制器(IBActions
委托)中公开NSApp
,然后将菜单项连接到这些操作。这是一种非常标准的做事方式。如果你有很多菜单项,你也可以将功能分解为一个或多个连接到app控制器的控制器,并将菜单项连接到它们。