2011-05-06 64 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

相關問題